From 079d62f7a78ac1fa1bbd767125efbe1df2ebdd36 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Thu, 17 Sep 2026 03:42:09 -0700 Subject: [PATCH 1/5] Repair transcript fidelity and measurement result boundaries for 0.2.0 --- .agents/skills/README.md | 4 +- .agents/skills/gonol-build/SKILL.md | 98 ++-- .agents/skills/meta-module-build/SKILL.md | 62 +- .agents/skills/msdmd/SKILL.md | 539 +++++++++--------- .agents/skills/msdmd/parsers/universal.py | 33 +- .agents/skills/msdmd/parsers/universal.ts | 29 +- .../msdmd/references/metadata-conventions.md | 200 +++++++ .agents/skills/test-build/SKILL.md | 170 +++--- .github/workflows/ci.yml | 21 +- .github/workflows/skill-compliance.yml | 6 +- AGENTS.md | 153 +++-- CANON.md | 85 +-- CLAUDE.md | 56 +- README.md | 64 +-- docs/EDCM_MATHEMATICS.md | 26 +- docs/GONOL_LANGUAGE_BOUNDARY.md | 201 ++----- docs/UPGRADE_AVENUES.md | 60 ++ docs/integrity-gates.md | 4 +- docs/migrations/0.2.0-audit-repair.md | 83 +++ docs/shared-stack-result.md | 25 +- edcm/__init__.py | 2 +- edcm/corpora/multiwoz21_booking_holdout.py | 2 +- edcm/gonol.py | 2 + edcm/integrity.py | 2 +- edcm/language/__init__.py | 2 + edcm/layers.py | 34 +- edcm/measurement/__init__.py | 2 +- edcm/measurement/compress.py | 44 +- edcm/measurement/parser/turns_rounds.py | 62 +- edcm/shared_stack.py | 100 ++-- edcm/ucns_adapter.py | 2 + edcm/ucns_edcm_experiments.py | 4 +- edcm/ucns_edcm_experiments_v2.py | 4 +- edcm/ucns_edcm_experiments_v3.py | 4 +- edcm/ucns_edcm_experiments_v4.py | 4 +- edcm_msdmd.ts | 43 +- llms.txt | 16 + tests/test_audit_regressions.py | 136 +++++ tests/test_gonol_language_authority.py | 83 +-- tests/test_packaging.py | 2 +- tests/test_shared_stack_contract.py | 2 +- 41 files changed, 1457 insertions(+), 1014 deletions(-) create mode 100644 .agents/skills/msdmd/references/metadata-conventions.md create mode 100644 docs/UPGRADE_AVENUES.md create mode 100644 docs/migrations/0.2.0-audit-repair.md create mode 100644 llms.txt create mode 100644 tests/test_audit_regressions.py diff --git a/.agents/skills/README.md b/.agents/skills/README.md index 5caa7c1a..3cdda3e9 100644 --- a/.agents/skills/README.md +++ b/.agents/skills/README.md @@ -3,12 +3,12 @@ This directory contains repo-local copies of canonical skills from `The-Interdependency/skill-lib`. -Source commit: `c14ee9d500579a4b5d6821f62c9d82ca96e73608` +Source commit: `dd5027d99516831c0dcb83a176a67140d3819b66` Repo-local copies are not the source of truth. Edit `skill-lib` first, then propagate from the canonical source. -Installed skills: +Skills refreshed from the source commit above: - `canon/` - `domain-claims/` diff --git a/.agents/skills/gonol-build/SKILL.md b/.agents/skills/gonol-build/SKILL.md index 86747c85..2590edf0 100644 --- a/.agents/skills/gonol-build/SKILL.md +++ b/.agents/skills/gonol-build/SKILL.md @@ -1,80 +1,91 @@ --- name: gonol-build -description: Construction, closure, and replay contract for gonols across UCNS and EDCM. Load this when building or reviewing UCNS geometry used by gonols, or building EDCM character, word, definition, or recursive-relation gonols. UCNS owns geometry; EDCM owns text construction. The required EDCM order is characters -> words -> definitions -> recursive gonol relations. Pronunciation is not required unless an explicitly declared later experiment makes it part of the construction. Do not load for unrelated geometry, ordinary prose editing, or measurement over already-closed gonols. +description: Construction, closure, and replay discipline for active gonol-language research. Load this when building or reviewing language constructions made from UCNS gonol objects in The-Interdependency/stack, or when checking closure, atomic participation, provenance, replay, and unresolved geometry boundaries. UCNS owns gonol objects, constructors, and geometry; Stack owns active construction research; EDCM owns measurement/evaluation only. Closed gonols participate atomically at admissible consuming scales; no universal adjacent-scale ladder is required. Pronunciation is not required unless an explicitly declared construction makes it part of the build. Do not load for unrelated geometry, ordinary prose editing, or measurement over already-closed gonols. --- # gonol-build -Use this skill to keep gonol construction on the declared architecture and nothing else. +Use this skill to keep gonol-language construction on the declared architecture and nothing else. ## Workflow -1. Resolve the current UCNS and EDCM authorities before building. +1. Resolve the exact UCNS authority and the exact owning Stack research workspace before building. 2. Before launching construction or replay whose completion materially depends on scarce resources, preflight the resources required to finish the declared scope. -3. Keep the EDCM order load-bearing: characters -> words -> definitions -> recursive gonol relations. -4. Close each completed gonol before it participates atomically at the next declared scale. -5. If required UCNS geometry is unresolved, preserve that boundary as `hmmm`. -6. Replay the complete declared scope only where replay is required by the governing protocol. +3. Resolve the owning Stack workspace's declared source/admission profile, participant eligibility, relations, and closure rules; do not impose a universal adjacent-scale ladder. +4. Consume UCNS gonol constructors and geometry rather than defining a competing gonol object in the language layer. +5. Close each completed gonol before it participates atomically at an admissible consuming scale. +6. If required UCNS geometry is unresolved, preserve that boundary as `hmmm`. +7. Replay the complete declared scope only where replay is required by the governing protocol. ## Authority ```text -UCNS = geometry -EDCM = text-domain gonol construction +UCNS = gonol objects, constructors, and underlying geometry +Stack = active language-gonol construction research workspaces +EDCM = measurement and evaluation of constructed outputs skill-lib = construction/replay discipline ``` -Resolve the current UCNS and EDCM authorities before building. Do not move text semantics into UCNS or invent geometry in EDCM. +Repository placement does not transfer authority. A Stack workspace may construct English, Python, French, TypeScript, or another domain from UCNS gonol objects without thereby owning UCNS geometry. Language workspaces consume UCNS construction authority; they do not redefine it. EDCM may measure a completed construction without defining that construction. -## EDCM construction contract +Historical EDCM constructor names and sealed artifacts remain valid historical identities for replay. They do not restore active construction authority to EDCM. + +## Active construction contract ```text -characters -> words -> definitions -> recursive gonol relations +declared source/admission profile ++ eligible already-closed participants ++ constitutive relation ++ UCNS gonol construction +-> closure ``` -This order is load-bearing. +The active constructor contract belongs to the owning Stack research workspace. Resolve its exact files and commit before selecting participants. For the current English research workspace this includes `research/english-gonol/`; for current Python research this includes `research/python-gonol/`. These paths are workspace locations, not universal language canon. -- Every admitted character is a gonol. -- Ordered character gonols close into a word gonol. -- A closed word gonol is atomic at the consuming scale while its constituent identities, order, multiplicity, source positions, and provenance remain recoverable. -- Definition gonols are constructed from the applicable closed word gonols and exact source definition evidence. -- Recursive relations are constructed from already-closed gonols without reopening or erasing their internal structure. +The sequence `characters -> words -> definitions -> recursive relations` may describe a particular construction, but it is not a mandatory ladder for every language or every admitted construction. -Do not insert another required stage into this sequence unless the governing contract is explicitly changed. +- Every admitted primitive occurrence required by the active profile remains individually addressable. +- Ordered closed gonols may close into a higher construction when the owning workspace authorizes that relation. +- Any closed gonol is atomic at an admissible consuming scale while constituent identities, order, multiplicity, source positions, relations, and provenance remain recoverable. +- Constitutive relationships belong inside the construction. Sidecars may index or cache them but must not replace them. +- Recursive relations consume already-closed gonols without reopening or erasing their internal structure. + +Do not invent participant eligibility, a required intermediate stage, semantic axes, or a geometry law merely to complete a pipeline. ## Pronunciation boundary -Pronunciation is not required for this construction. Pronunciation, phonetic spelling, IPA, audio, or other sound representations must not alter gonol identity, closure, ordering, or relations unless a later explicitly declared experiment makes phonology part of its construction. +Pronunciation is not required by default. Pronunciation, phonetic spelling, IPA, audio, or other sound representations must not alter gonol identity, closure, ordering, or relations unless the owning construction explicitly admits phonology. -Source pronunciation data may remain source metadata. It is not a dependency of the current build. +Source pronunciation data may remain evidence or metadata. It becomes construction only under an explicit source/admission contract. ## Construction invariant -At every scale: +At every admitted scale: ```text -ordered eligible gonols --> authorized UCNS geometric relation/application +ordered eligible closed gonols +-> constitutive relation declared by the owning workspace +-> UCNS gonol construction / authorized geometric application -> closure -> deterministic identity + provenance receipt --> atomic participation at the next declared scale +-> atomic participation at an admissible consuming scale ``` -Preserve exact source identity, occurrence order, multiplicity, and provenance. Do not normalize, deduplicate, infer relations, or substitute tokens, embeddings, hashes, or another representation for gonol identity unless the active contract explicitly authorizes it. +Preserve exact source identity, occurrence order, multiplicity, relation identity, and provenance. Do not normalize, deduplicate, infer relations, or substitute tokens, AST nodes, compiler objects, embeddings, hashes, or metadata for gonol construction unless the active contract explicitly authorizes their role. If required UCNS geometry is unresolved, preserve that boundary as `hmmm`; do not fill it with an invented rule. ## Candidate boundary -An unresolved constructor is permission to construct a named, bounded candidate; it does not block declared experimentation. It blocks promotion beyond the evidence, not construction or testing. +An unresolved constructor or geometry operation permits named, bounded candidate work where the declared evidence permits it. It does not block declared experimentation. It blocks promotion beyond the evidence. ## Completion and replay -Before launching a construction or replay run whose completion materially depends on scarce resources, preflight the resources required to finish it. If the preflight cannot establish enough resource confidence to finish the declared scope, do not start the compute run; record the unresolved resource boundary as `hmmm` or narrow the declared scope under the governing protocol. Once a healthy admitted run begins, let it reach its natural terminal condition unless a genuine safety/resource boundary or preregistered load-bearing stop condition fires. Do not add arbitrary wall-clock limits. +Before launching a construction or replay run whose completion materially depends on scarce resources, preflight the resources required to finish it. If the preflight cannot establish enough resource confidence to finish the declared scope, do not start the compute run; record the resource boundary as `hmmm` or narrow the declared scope under the governing protocol. Once a healthy admitted run begins, let it reach its natural terminal condition unless a genuine safety/resource boundary or preregistered load-bearing stop condition fires. Do not add arbitrary wall-clock limits. A completion claim requires: -1. exact UCNS, EDCM, source/profile, and constructor identities; +1. exact UCNS, Stack workspace, source/profile, and constructor identities; 2. the complete declared source scope; 3. deterministic construction receipts; and 4. independent complete replay where replay is required by the governing protocol. @@ -83,26 +94,37 @@ Replay establishes reproducibility of that construction only. It does not by its ## Usage guidance -For text construction, start in EDCM and consume current UCNS geometry. +For active gonol-language construction, start in the owning research workspace inside `The-Interdependency/stack` and consume current UCNS gonol constructors/geometry. Do not start in EDCM. ```text -UCNS: geometry -EDCM: characters -> words -> definitions -> recursive gonol relations +UCNS: gonol objects + constructors + geometry +Stack: active construction research +EDCM: measurement/evaluation only +``` + +Use `stack-update` when ownership, placement, authority, lifecycle, or promotion changes. Use `interdependent-work-graph` whenever the task crosses repository boundaries. + +Run skill-lib's local authority regression gate after changing this boundary: + +```bash +bash tools/check_gonol_authority.sh ``` -When a word closes, use that word gonol atomically at the next scale. Ignore pronunciation unless a future explicit construction says otherwise. +When a gonol closes, use it atomically at an admissible consuming scale. Ignore pronunciation unless an explicit construction says otherwise. ## Anti-patterns -- Moving text semantics into UCNS or inventing geometry in EDCM. -- Inserting another required EDCM stage without an explicit contract change. -- Letting pronunciation alter gonol identity, closure, ordering, or relations unless a later explicitly declared experiment makes phonology part of its construction. -- Normalizing, deduplicating, inferring relations, or substituting tokens, embeddings, or hashes for gonol identity unless the active contract explicitly authorizes it. +- Assigning active gonol or language construction authority to EDCM. +- Defining a competing gonol object in an English, Python, or other language workspace instead of consuming UCNS construction authority. +- Treating Stack placement as transfer of UCNS geometry authority. +- Imposing an adjacent-scale ladder or inventing an eligible relation without the owning workspace's authority. +- Letting pronunciation alter gonol identity, closure, ordering, or relations unless an explicit construction admits it. +- Normalizing, deduplicating, inferring relations, or substituting tokens, AST nodes, embeddings, hashes, or metadata for gonol identity unless explicitly authorized. - Adding arbitrary wall-clock limits to a healthy admitted run. - Treating replay as semantic quality, measurement validity, cognition, or extra-scope canon. ## hmmm - exact UCNS geometric operations that remain unresolved in current implementation; -- any future construction that explicitly adds phonology or another stage; +- future repository/package placement for graduated language-gonol artifacts where no repository presently exists; - any recursive relation whose governing source or geometry is not yet established. diff --git a/.agents/skills/meta-module-build/SKILL.md b/.agents/skills/meta-module-build/SKILL.md index e9ca23f0..f3507e66 100644 --- a/.agents/skills/meta-module-build/SKILL.md +++ b/.agents/skills/meta-module-build/SKILL.md @@ -1,15 +1,20 @@ --- name: meta-module-build -description: Metadata-first module build skill built on msdmd. Use this when turning a capability idea into a bounded module manifest, file plan, public/internal surface, permission boundary, tests, docs, rollout, and rollback notes before implementation. +description: Native-first module planning built on msdmd. Consume existing manifests, schemas and design declarations; supplemental MODULE_BUILD blocks record remaining purpose, surface, boundary, test, rollout and rollback obligations. Load this when turning a capability idea into a bounded module manifest and file plan before implementation. --- -GPT generated; context, prompt Erin Spencer - # meta-module-build — Metadata-first module scaffolding -`meta-module-build` is an application of [msdmd](../msdmd/SKILL.md). It uses self-declared metadata to keep a proposed module's purpose, surfaces, dependencies, boundaries, tests, and rollout notes visible beside the files that implement it. +GPT generated; context, prompt Erin Spencer -Read `msdmd/SKILL.md` first. This skill inherits the block syntax, parser contract, and visible gap-reporting requirement. +`meta-module-build` is an application of [msdmd](../msdmd/SKILL.md). It +keeps proposed purpose, surfaces, dependencies, boundaries, tests and rollout +notes attributable to the sources that own them. + +Read `msdmd/SKILL.md` first. This skill inherits its source/provenance, native +reader support, supplemental block and information-coverage contracts. +Implementation status: this is a consuming-repo planning/runner contract; +this repo does not ship a MODULE_BUILD runner or native planning readers. ## Doctrine @@ -21,9 +26,21 @@ intent -> manifest -> file plan -> tests -> scaffold -> reviewable change If a field is not known, write `hmmm`. Do not guess certainty into the manifest. +## Native-first coverage + +Consume existing package/module manifests, schemas, source-owned design +records and explicit rollout/test declarations before requesting supplemental +metadata. Preserve owning scope and source references. A package manifest is +not automatically a module plan: map only information it actually expresses. + +The build's semantic obligations remain required, but their native owners need +no MODULE_BUILD copies. Supplement genuinely unexpressed intent. Unsupported +mapping is unresolved coverage, not absence. Native readers remain implementation +work, not capabilities supplied by this text. + ## The block -A module owns its build declaration in a `MODULE_BUILD` block: +A module may supplement its build declaration with a `MODULE_BUILD` block: ```python # === MODULE_BUILD === @@ -47,7 +64,9 @@ A module owns its build declaration in a `MODULE_BUILD` block: ## Field schema -Required: +This syntax governs supplemental MODULE_BUILD entries. Native sources retain +their own schemas and must satisfy the applicable planning obligations without +invented IDs or copied fields. Required for a supplemental entry: | Field | Meaning | |---|---| @@ -62,7 +81,7 @@ Required: | `rollout` | How the module becomes active. | | `rollback` | How to disable or remove it cleanly. | -Boundary fields are required because module generation often crosses hidden lines: +Boundary information is required because module generation often crosses hidden lines: | Field | Meaning | |---|---| @@ -139,21 +158,31 @@ Do not use raw factorization sentinels for A0-facing claims when a scoped envelo A `MODULE_BUILD` runner should: -1. parse all `MODULE_BUILD` blocks using the msdmd universal parser; -2. validate required fields; -3. report boundary fields visibly; -4. report modules without `MODULE_BUILD` as coverage gaps; -5. optionally fail in strict mode when required build metadata is missing; +1. extract supported native planning metadata and parse supplemental + `MODULE_BUILD` blocks using the msdmd universal parser; +2. validate native mappings and supplemental fields under their own schemas; +3. report boundary information and its owning sources visibly; +4. report genuinely absent required planning information only after capable + inspection; keep missing blocks separate as adoption observations; +5. fail strict mode on missing information, required unsupported extraction or + unresolved conflicts, rather than accepting incomplete coverage; 6. emit a review summary grouped by `module_kind` and boundary risk. +## Validation + +A supported native planning fixture must satisfy the information it actually +expresses without a MODULE_BUILD copy. Include missing rollback, unresolved +boundary, unsupported mapping and same-name/different-scope cases. + ## Anti-patterns - Building code first and writing the manifest after. -- Omitting boundary fields because the module feels small. +- Omitting boundary information because the module feels small. - Marking unknowns as solved instead of `hmmm`. - Using implementation-shaped ids that do not explain the protected capability. - Adding UI or route behavior without declaring metadata expectations. - Treating frontier-domain UCNS results as absolute claims. +- Demanding a second MODULE_BUILD copy of already-owned native information. ## Completion criteria @@ -169,10 +198,13 @@ or scaffold PR with tests and docs ``` -It is incomplete if it only produces an idea, a patch with no manifest, or a module with no boundary/test plan. +The manifest may be composed from source-linked native declarations and +supplemental entries. An idea alone, a patch with no manifest, or a module with +no boundary/test plan remains incomplete. ## hmmm +Native planning readers remain consuming-repo implementation work. Default unresolved items for new modules: ```text diff --git a/.agents/skills/msdmd/SKILL.md b/.agents/skills/msdmd/SKILL.md index ffa10c40..186593c4 100644 --- a/.agents/skills/msdmd/SKILL.md +++ b/.agents/skills/msdmd/SKILL.md @@ -1,323 +1,318 @@ --- name: msdmd -description: Module Self-Declared Metadata in Markdown — the foundational convention where each module declares its own structured metadata in a fenced comment block. Other skills in this lib (doc-build, cap-build, deps-build, owner-build, test-build, meta-module-build, risk-boundary-build, ratios, etc.) are thin applications on top of this convention. Load this when authoring a new metadata-driven skill, when extending the block schema, or when building a parser/executor for a new application. +description: Module Self-Declared Metadata in Markdown — native-first collection of metadata already expressed by code, documentation, manifests, schemas, tooling, and evidence formats, with MSDMD blocks only for otherwise unexpressed information. Load this when creating or revising metadata-driven skills, collecting repository metadata, integrating a metadata convention, building parsers or collection consumers, or auditing metadata coverage and provenance. --- -# msdmd — Module Self-Declared Metadata in Markdown +# msdmd — consume declarations where they already live + +## Contract and usage guidance + +MSDMD consumes existing metadata conventions explicitly. It does not require +native declarations to be rewritten as MSDMD blocks. Its own blocks supplement +information that an owning source cannot already express adequately. + +Load this skill before changing metadata ingestion, coverage policy, or a +metadata-driven application. Read [the convention catalogue and reader +contract](references/metadata-conventions.md) for the families actually present +in the target repository. That catalogue is a discovery baseline, not a closed +allowlist and not a claim that every reader has been implemented. + +This is the foundational metadata-block skill, expanded to native-first +interoperability; it owns the common ingestion contract, not every language's +syntax. Ordinary prose editing with no metadata contract is a non-trigger. + +**Implementation boundary:** at the reviewed source revision +`22c2c5702d14fb4b0faeb717777ecab2665770a1`, `collect.py` implements MSDMD-block +collection and `collection.ts` represents block-origin declarations. The native +reader, provenance, conflict, and information-coverage requirements below are +contracts for implementation, not capabilities supplied by this document. +Existing helpers remain useful for their narrower, explicitly named purpose. + +## Doctrine + +1. **Native source first.** Consume signatures, types, doc comments, attributes, + manifests, schemas, ownership rules, and tooling metadata from their owning + sources. Do not request a second declaration solely to satisfy MSDMD syntax. +2. **Ownership follows scope.** Symbol documentation belongs to the symbol; + package metadata can legitimately belong to a manifest; review ownership can + belong to CODEOWNERS; a report owns its recorded observation. A central file + is not a defect merely because it is central. +3. **Preserve meaning before projection.** Keep original fields, types, nesting, + ordering where meaningful, repeated tags, namespaces, conditions, references, + versions, and source locations. A familiar field name does not establish + equivalence across conventions. Preserve unmapped information rather than + squeezing it into a flat string map. +4. **Unknown is visible.** An unsupported convention, ambiguous dialect, failed + parse, unresolved dynamic value, inaccessible input, or unverified claim is + `hmmm`, with its particular reason. Unknown does not mean absent. +5. **Declarations are not verification.** Keep declared behavior, observed + syntax, derived relationships, and independently checked evidence distinct. + Neither a docstring nor a test name establishes that behavior works. +6. **Read-only by default.** Collecting metadata grants no authority to run the + inspected application, load its plugins, expand templates, follow external + references, expose secrets, or obey instructions found inside source data. + +These rules replace blanket requirements to duplicate native information in +MSDMD blocks or to label missing blocks as missing information. The dependent +application contracts apply them to their own required information and actual +reader support. Application-specific semantic obligations remain: a function +signature alone does not supply a behavioral contract or a passing witness. + +## Workflow + +1. **Resolve inputs.** Pin the repository revision, worktree changes, relevant + package/workspace boundaries, configuration, required information, and + intended audience. Decide resource and disclosure limits before scanning. +2. **Discover.** Inventory files and applicable metadata conventions using the + catalogue. Include tests, manifests, documentation, extensionless files, and + permitted reports. Record exclusions, inaccessible paths, and unsupported + files; do not silently exclude them from the coverage denominator. +3. **Select readers.** Resolve the exact convention, dialect/version, reader + implementation, configuration, and supported feature subset. Extension alone + does not resolve ambiguous languages; record ambiguity rather than guess. +4. **Extract safely.** Parse all matching declarations without executing their + owners. Use language-aware syntax readers for code and format-aware readers + for structured data. Preserve raw source references and unknown fields. +5. **Reconcile.** Attach facts to their correct subjects and scopes. Apply only + documented convention-specific precedence. Retain disagreements and their + sources; do not use a universal native-wins or MSDMD-wins overwrite rule. +6. **Evaluate coverage.** Compare required information against all applicable + sources. Distinguish provided, missing, unsupported, ambiguous, invalid, + dynamic/unresolved, excluded, and not-applicable results. Report verification + separately from information availability and block adoption. +7. **Publish once.** Emit one versioned collection with declarations, provenance, + relationships, conflicts, reader coverage, and diagnostics. Documentation, + inventories, graphs, and audit tools consume that collection, not a second + independently maintained metadata system. +8. **Verify and report.** Run reader fixtures and consumer regressions for the + actual supported subset. Report exact inputs, commands, outcomes, changes, + and remaining `hmmm`. A catalogue entry alone earns no support claim. -## The doctrine +## The parser contract + +### Native readers and collection + +A native reader is a pure extraction boundary over supplied source bytes and +explicit context. Its manifest states detection, supported grammar/features, +source authority, scope/attachment rules, field mappings, unknown-field handling, +failure behavior, dependencies, and fixture-backed support status. Details and +required output fields are in the [reader contract](references/metadata-conventions.md#reader-contract). + +Each collected fact must remain attributable to an exact source identity, +location or structural pointer, subject, convention, and extraction method. +Generated identifiers are collector addresses, not falsely attributed native +IDs. Identical names in different packages, scopes, or revisions remain distinct. +Cross-revision identity requires an explicit mapping, not a line-number guess. + +Original syntax and an immutable source reference preserve lossless access; +normalized projections can be lossy only when labeled and linked back to that +source. Sensitive material stays access-controlled or explicitly redacted; +source preservation does not require publishing credentials or private content. + +Do not repurpose `MsdmdDeclaration.block` to mean JSDoc, TOML, or any other +non-block convention. Introduce a versioned native-capable collection schema +with explicit migration and consumer negotiation. The existing `MsdmdCollection` +remains a block-only format until that implementation lands. Refuse silent +projection when an old consumer would lose required information. + +## The runner protocol -Every cross-cutting fact a module owns — its behavior obligations, -public documentation, declared capabilities, dependency edges, owner, -runtime boundaries, or executable evidence — should live **in the same -file as the module that owns that fact**, in a structured comment -block. A meta-runner walks the tree, parses every block, and acts on -it. +### Information coverage, not compulsory annotation -Modules without the relevant block surface as visible coverage gaps in -the runner output. Coverage is observable, not implicit. +A missing `DOCS` block is a **block-adoption observation**, not proof of missing +documentation. A missing `OWNERS` block does not establish an unowned file before +applicable native ownership rules are evaluated. A missing reader cannot earn +either a clean bill of health or a missing-information finding. -This is the inverse of the conventional "keep your docs/tests/configs in -sync with code" approach, which fails because the contract and the -implementation live in different files. Anyone can delete the code and -forget the doc; the lie persists. msdmd makes the lie structurally -visible: when the implementation-owning file disappears, its owned -block disappears in the same diff. +A missing-information result requires an applicable obligation, a completed +search of its declared eligible sources, and capable readers that found no +satisfying declaration. Partially recovered metadata remains useful, but does +not justify a complete-coverage claim. Count unknown/excluded scope explicitly. -For tests, ownership is split rather than flattened: source modules own -`CONTRACTS` obligations; test modules own `CHECKS` evidence that -claims to prove those obligations. See -[`test-build/SKILL.md`](../test-build/SKILL.md) and -[`doctrine/msdmd-checks.md`](../doctrine/msdmd-checks.md). +Coverage output must name its denominator, eligibility rules, reader support, +exclusions, conflicts, and unresolved count. Separate at least information +availability, supported extraction scope, MSDMD-block adoption, and verified +behavior. A green aggregate cannot hide unsupported required inputs. + +Strict checks fail on missing required information, unresolved required scope, +parse/schema errors, or unresolved required-field conflicts. Optional unknowns +remain visible without necessarily blocking unrelated work. A non-strict +inventory may complete successfully while clearly reporting incomplete coverage. ## Block syntax -```python -# === === -# id: -# : -# : -# -# id: -# : -# === END === -``` +### Supplemental MSDMD declarations -### Universal rules - -- **Fence**: `=== ===` opens, `=== END ===` - closes. Block name is uppercase snake_case (e.g. `CONTRACTS`, - `CHECKS`, `DOCS`, `CAPABILITIES`, `OWNERS`). -- **Comment marker**: whatever is idiomatic for the file's language. The - reference parsers auto-detect these line-comment families by extension: - `#` for Python, Ruby, Elixir, shell, Perl, R, Julia, PowerShell, Tcl, and - Raku; `//` for TypeScript/JavaScript, Rust, Go, Java, C, C++ (including - `.c+`, `.c++`, `.cxx`, and header variants), Swift, Kotlin, C#, - Objective-C++, Scala, Dart, Zig, Groovy, and PHP; `--` for SQL, Lua, - Haskell, Ada, VHDL, and Lean; `%` for Erlang and Prolog; `;` for - Clojure/Lisp/Scheme/Racket; `!` for Fortran; `'` for Visual Basic; and - `*>` for COBOL. The marker appears at the start of every line in the block. - `COMMENT_MARKERS` in both universal parsers is the exact extension registry. -- **Entry boundary**: every entry begins with `id:`. The id must be - unique within its block and stable across refactors (so it can be - referenced from external tooling). -- **Field lines**: indented one level beneath the id (two spaces of - visible indent inside the comment). Field names are lowercase - snake_case followed by `:` and a value. -- **Multiple blocks per file**: a module may declare more than one - block, of the same or different types. The parser concatenates - entries. -- **Multiple block types per file**: a module may declare both - `CONTRACTS` and `DOCS` (and any others). Each is parsed - independently by its respective application. - -### Example (Python source module) +The existing block syntax remains supported; its purpose is supplementation, +not redeclaration of everything already present in native syntax. ```python # === CONTRACTS === -# id: chat_get_other_owner_404 -# given: GET /api/v1/conversations/{id} with x-user-id != row.user_id -# then: 404 (existence non-disclosure) +# id: other_owner_hidden +# given: a request for another owner's record +# then: return 404 without disclosing existence # class: security # === END CONTRACTS === ``` -### Example (Python test module) +Source modules own `CONTRACTS` obligations. Test modules own `CHECKS` witnesses; +`proves` produces `claims_proves`, not an automatic proof. Keep `call` with the +witness, not the source obligation. See [test-build](../test-build/SKILL.md) +and the [CONTRACTS/CHECKS doctrine](../doctrine/msdmd-checks.md). + +The block parser contract is unchanged: parse the requested block type from +text into all matching flat string-valued entries; preserve declared fields; +return an empty list when that block is absent; leave field semantics to the +application. The universal Python and TypeScript helpers live in +`parsers/universal.py` and `parsers/universal.ts` and remain dependency-free. + +Fences use uppercase snake-case block names. Every entry starts with `id:`; +field names use lowercase snake-case, allowing digits after the first character, +and field lines are indented beneath the ID. The authoring contract requires +IDs to be unique within one block type in one owning file; multiple matching +blocks concatenate. A conforming identity validator must diagnose conflicting +IDs and qualify collection addresses by repository, file, block and entry. + +**That validation is not implemented by the shipped helpers.** The generic +collector does not diagnose duplicate IDs, and its edge `from` and `source_id` +values are bare entry IDs. The visualizer can merge distinct declarations when +IDs are reused across files or block types. Do not treat a successful collection +exit or its graph as evidence of identity validity. See the +[shipped helper limitations](#shipped-helper-limitations). + +Use the helpers' matching `COMMENT_MARKERS` registries for supported repeated +line-comment syntax; do not duplicate their language lists in runners. Native +block comments, docstrings, XML documentation, or manifest syntax require their +own readers, not invalid adaptations of line-comment fences. Ambiguous suffixes +such as `.m` require explicit language context. Preserve valid first-line +shebangs and the separate [RATIOS boundary contract](../ratios/SKILL.md). -```python -# === CHECKS === -# id: check_chat_get_other_owner_404_http -# proves: chat_get_other_owner_404 -# call: self::test_chat_get_other_owner_404_http -# requires: python3, posix_shell -# timeout: 20 -# mutates: db -# cleanup: transaction_rollback -# === END CHECKS === -``` +## Field naming conventions -### Example (TypeScript source module) +Reserved fields retain their existing meanings: `id` identifies the entry; +`class` groups it; `summary` describes it; `call` addresses a witness; +`proves` names claimed obligations; `requires` is application-qualified; +`owner` declares responsibility; `since` records introduction; `deprecated` +records a retirement declaration. Observing a native deprecation grants no +permission to delete someone else's code. Authoring or retiring MSDMD mechanisms +requires the owning change and its supported replacement or explicit removal. -```typescript -// === CONTRACTS === -// id: chat_input_send_disabled_while_pending -// given: a message is in flight -// then: send button is disabled and shows pending state -// class: ux_correctness -// === END CONTRACTS === -``` +## Worked example -### Example (Elixir) +An unchanged repository contains: -```elixir -# === CAPABILITIES === -# id: agent_supervisor_dynamic_spawn -# summary: spawns child agents under a DynamicSupervisor with max_children=cap -# exposes: AgentSupervisor.start_child/1 -# === END CAPABILITIES === +```python +# src/example/math.py +def double(value: int) -> int: + """Return twice the supplied value.""" + return value * 2 ``` -The block content is identical across languages — only the comment -marker changes. - -## The parser contract - -A msdmd parser is a pure function over file text: - +```toml +# pyproject.toml +[project] +name = "example" +version = "1.0.0" ``` -parse(file_text: str, block_name: str) -> list[Entry] + +```text +# .github/CODEOWNERS +/src/example/ @example/maintainers ``` -where `Entry` is a flat `dict[str, str]` containing at minimum the -`id` field plus whatever fields the entry declared. The parser: - -- Returns all entries from all matching blocks (using - `re.finditer`-style iteration, not just the first block). -- Does not interpret or validate field semantics — that's the - application's job. An entry missing a required field surfaces as an - error in the executor, not in the parser. -- Does not fail on missing block type — returns empty list if no block - of that name exists. - -A reference implementation in pure stdlib Python lives at -`parsers/universal.py`; the TypeScript equivalent at `parsers/universal.ts`. -Both commit to zero non-stdlib dependencies so you can copy them into -any project. - -Extension detection refuses ambiguous suffixes rather than sniffing content. -For example, `.m` can mean Objective-C or MATLAB/Octave and therefore has no -automatic marker. A caller that already knows the language may still call -`parse_text` / `parseText` with an explicit marker. Languages that cannot carry -the msdmd shape as repeated line comments need a future versioned syntax -extension; they are not approximated with an invalid fence. - -The paired RATIOS helper preserves the interpreter boundary: a non-empty -line-1 shebang may precede opening RATIOS, which must then occupy line 2 with no -gap. See [`ratios/SKILL.md`](../ratios/SKILL.md) for the complete seal contract. +With tested readers for those conventions, collect the signature and docstring +at symbol scope, package identity at package scope, and the applicable review +ownership rule at path scope. Retain every original source reference. No MSDMD +blocks need to be inserted. The return annotation is a declaration, not a test +result. CODEOWNERS review responsibility is not automatically authorship, +operational ownership, or proof of a team's live permissions. -## Repo collection point and visualizer +With only the currently shipped block collector, this repository cannot receive +a native-information coverage verdict. Report that reader gap explicitly. -Every consuming repo SHOULD maintain one repo-level collection point named -`_msdmd.ts` (for example, `a0_msdmd.ts`). This file is the -canonical aggregation surface for all parsed msdmd declarations in that -repo. It does not replace module-local blocks; it is generated from them -or maintained as a thin index over them. - -The collection point SHOULD use the shared shapes in `msdmd/collection.ts` -(or a verbatim copy in consuming repos) and export a `MsdmdCollection`: - -```typescript -import { defineMsdmdCollection } from "./.agents/skills/msdmd/collection"; - -export default defineMsdmdCollection({ - repo: "", - declarations: [ - { file: "path/to/module.py", block: "CONTRACTS", id: "...", fields: { summary: "..." } }, - { file: "tests/test_module.py", block: "CHECKS", id: "...", fields: { proves: "..." } }, - ], - gaps: [ - { file: "path/to/module.py", missing: ["CONTRACTS", "DOCS"] }, - ], - edges: [ - { from: "module_a", to: "module_b", kind: "requires", source_block: "DEPENDENCIES", source_id: "..." }, - { from: "check_module_a", to: "module_a_contract", kind: "claims_proves", source_block: "CHECKS", source_id: "..." }, - ], -}); - -export const declarations = []; -export const gaps = []; -``` +## Repo collection point and visualizer -A repo-level msdmd visualizer SHOULD read `_msdmd.ts` and render -relationships between modules using the `MsdmdEdge` shape: -`DEPENDENCIES.requires`, `CAPABILITIES.exposes`, `OWNERS.owner`, -`BOUNDARIES` risk fields, `DOCS.covers`, `CHECKS.call`, -`CHECKS.proves` as `claims_proves`, and any `requires` edges shared -across application skills. The visualizer is a consumer of the -collection point, not a second metadata source. +### Existing helper usage -If a repo has no collection point or visualizer yet, record that as `hmmm` in -repo-local planning rather than pretending the graph exists. +`skills.json` retains `status: runnable` and `runner: msdmd/collect.py` for +shipped block collection. `runner_scope: msdmd-blocks-only` bounds that capability; +`native_ingestion.status: contract` with no runner separates the unimplemented +native-reader contract. Neither index field upgrades helper behavior. -A small stdlib generator prototype lives at `msdmd/collect.py`. Consuming repos -can run it directly or copy it as a starting point: +These commands collect and visualize **MSDMD blocks only**: ```bash -python -m msdmd.collect --root . --repo --out _msdmd.ts +python -m msdmd.collect --root . --repo example --out example_msdmd.ts +python -m msdmd.visualize example_msdmd.ts --out example_msdmd.mmd ``` -The generator is intentionally conservative: it parses module-local blocks, -emits declarations, optional expected-block gaps, and simple relationship -edges from reserved fields. Repo-specific runners may enrich the output, but -should preserve the `MsdmdCollection` shape. +The existing collection's `gaps` field records expected-block gaps only. +`--expected-block` measures block presence, not native metadata completeness. +Do not use its output as the new information-coverage gate. Repo-level collection +points such as `_msdmd.ts` remain generated consumers of owning sources, +not editable replacements for them. No native-ingestion command is claimed here. -A minimal Mermaid visualizer prototype lives at `msdmd/visualize.py` and reads -raw JSON or generated TypeScript collection points: +### Shipped helper limitations -```bash -python -m msdmd.visualize _msdmd.ts --out _msdmd.mmd -``` +The declarations preserve `file`, `block` and `id`, but the current edge format +omits source-file identity and uses bare IDs; the Mermaid view can collapse +cross-file or cross-block identities. Duplicate IDs inside one file/block are +emitted without diagnostics. Qualified addresses and duplicate-ID validation +are required future validator behavior, not shipped guarantees. -The visualizer is deliberately small: it renders declaration nodes, normalized -edge relationships, and visible gap nodes. Rich repo-specific UIs should consume -the same collection shape rather than re-parsing source files. +Until implemented and tested with an explicit compatible schema/consumer +transition, use these helpers only for the disclosed inventory/prototype scope. +An identity-sensitive audit needs an independent, capable validator and an +unambiguous target-resolution policy. Without them, that required scope is +`hmmm`; a zero exit code cannot make it pass. This skill revision does not repair +the collector or visualizer runtime. +## Validation and acceptance -## The runner protocol +The [acceptance matrix](references/metadata-conventions.md#acceptance-matrix) +defines the native-reader tests. Its decisive case is an unchanged repository +with supported native conventions and zero MSDMD blocks: metadata is collected +accurately, unknowns stay visible, and no false missing-information findings are +manufactured. Pair it with cases where required information really is missing. -A msdmd runner combines a parser and an executor: +For a skill/index edit, run the repository's editorial gates separately: +```bash +python tools/build_codex_plugin_skills.py --apply +python tools/build_codex_plugin_skills.py --check +python tools/check_skill_lib_drift.py --warnings-fail +python tools/check_skill_compliance.py --warnings-fail +python -m unittest discover -s tests ``` -walk(root: Path, block_name: str) -> Iterator[(file: Path, entries: list[Entry])] -``` - -Implementation rules every runner MUST follow: - -1. **Walk the source tree** under a configurable root, skipping - conventional non-source paths (`__pycache__`, `node_modules`, - `.git`, build outputs, the runner's own test directory). -2. **Detect comment marker by extension**, not by content sniffing. Consume the - parser's `COMMENT_MARKERS` registry rather than maintaining a runner-local - language list. Python and TypeScript registries must remain identical. -3. **Parse all matching blocks** in each file. Multiple blocks of the - same type concatenate; entries from different blocks are - distinguishable only by id, not by source block. -4. **Visit modules without any block of the requested type** and emit - them as a separate "untested" / "undocumented" / "uncapable" gap - list. Truncate noise (e.g. show first 20, count the rest), but - never silently drop. Visibility is the whole point. -5. **Exit non-zero** when any entry fails the executor's check. The - gap list itself is informational unless the application opts in to - strict mode (in which case missing blocks are also a fail). - -## Field naming conventions -Reserved field names and their canonical meanings (for cross-skill -consistency): - -| Field | Meaning | -|---|---| -| `id` | Unique stable identifier within the block. Required on every entry. | -| `class` | Free-text tag for grouping (`security`, `correctness`, `idempotency`, etc.). The runner counts entries per class in summaries. | -| `call` | Executable target owned by an evidence/check declaration. Source `CONTRACTS` do not use this field for test topology. | -| `proves` | Comma-separated ids this evidence/check entry claims to prove. The collection edge kind is `claims_proves`; mutation sensitivity is a higher verification rung. | -| `summary` | One-sentence human description. | -| `requires` | Comma-separated dependency ids or host capabilities. Exact semantics are application-specific and must be documented by the skill that consumes it. | -| `owner` | Who is responsible (person, agent role, team). | -| `since` | Version or date this declaration was added. | -| `deprecated` | If present, marks the entry as scheduled for removal. | - -Application-specific fields (`given`, `then`, `expects`, `inputs`, -`outputs`, `mutates`, `cleanup`, `timeout`, etc.) are introduced by -individual SKILLs and documented in their own SKILL.md. - -## Authoring a new msdmd application - -1. **Pick a block name** that doesn't collide with an existing - application. Search the lib README for current names. -2. **Define the field schema** — which fields are required, which - optional, what types they carry. Document in your SKILL.md. -3. **Write the executor** — the function that takes parsed entries - and acts on them. Use the universal parser; do not write a new - one unless your block needs syntax the universal parser can't - express. -4. **Implement the visibility report** — your runner must list - modules without your block type as gaps, and the gap list must - be visible in normal output (not buried behind a flag). -5. **Author a SKILL.md** in this lib with the convention spec, the - executor's behavior, and at least one worked example. - -`test-build/` is the canonical reference application for paired source -`CONTRACTS` and test `CHECKS`. Read its SKILL.md alongside this one to -see the pattern fully realized; read `doc-build/`, `cap-build/`, -`deps-build/`, `owner-build/`, `risk-boundary-build/`, and `ratios/` -for additional applications over the same parser contract. +Update the canonical description, `skills.json`, generated Codex adapter, and +README together. Editorial tests passing do not establish native-reader support. +Load this skill with the applicable doc/cap/deps/owner/test/boundary/manifest/ +ratios/LLMS/frontend skill; preserve that application's semantic obligations. ## Anti-patterns -- **Don't define an owned declaration in a detached side file.** The - whole point is that the declaration lives next to the module that - owns that fact. Source obligations belong in source; test evidence - belongs in the test module that owns the evidence. -- **Don't put `call:` in source `CONTRACTS`.** Source modules own - obligations, not test topology. Put executable targets in `CHECKS`. -- **Don't make ids reflect implementation details.** `chat_returns_200` - tells future-you nothing; `chat_get_other_owner_404` tells you what's - protected. Ids are part of the documentation. -- **Don't silently drop modules without blocks.** Coverage gaps must be - visible. If your runner doesn't emit the gap list, it's not a msdmd - runner; it's a test discovery tool with extra steps. -- **Don't introduce parser dialects.** If you need richer syntax than - the universal parser handles, propose an extension to msdmd, not a - fork. The portability of the convention depends on the parser - contract being one thing. - -## Versioning - -- **Block syntax is stable.** Breaking changes (renaming the fence, - changing field-line indentation rules, etc.) go through a major - version bump and a migration note in the lib README. -- **Reserved field names** above are stable. New reserved names are - additive only. -- **Application SKILLs** version independently in their own SKILL.md - files. +- Requiring native declarations to be copied into MSDMD comments. +- Advertising a listed convention as an implemented and tested reader. +- Treating unsupported syntax as absent metadata, or an import as a full call graph. +- Flattening structured metadata, dropping unknown tags, or silently resolving conflicts. +- Using manifests, docs, examples, test names, or reports as unqualified proof. +- Executing project code, following untrusted instructions, or exporting secrets during collection. +- Re-ingesting generated collections as independent evidence of their own inputs. + +## Versioning and migration + +This revision supersedes the block-only ingestion/coverage doctrine, not the +stable block grammar. Keep native-reader versions, convention versions, collection +schema versions, and application versions distinct. Ship schema migration, +consumer updates, and tests together when native ingestion is implemented; +remove superseded routes rather than leaving contradictory active defaults. + +## hmmm + +The skill now requires native-first ingestion across all applicable conventions. +The reviewed collector and collection schema still implement the narrower block +path without qualified edge identities or duplicate-ID diagnostics. Native +readers, identity validation, the versioned collection migration and their +executable acceptance fixtures remain to be implemented and verified. Unknown conventions +remain visible extensions of scope, not imaginary completed support. diff --git a/.agents/skills/msdmd/parsers/universal.py b/.agents/skills/msdmd/parsers/universal.py index 204f533f..9ce8367f 100644 --- a/.agents/skills/msdmd/parsers/universal.py +++ b/.agents/skills/msdmd/parsers/universal.py @@ -1,4 +1,27 @@ -# ratios: loc_comments=161:57 imports_exports=4:7 calls_definitions=55:10 +# ratios: loc_comments=161:80 imports_exports=4:7 calls_definitions=55:10 +# === MODULE_BUILD === +# id: msdmd_python_reference_parser +# module_name: universal +# module_kind: instrument +# summary: parses canonical line-comment metadata without executing inspected source +# owner: The Interdependency skill-lib +# public_surface: COMMENT_MARKERS, RATIO_IDS, marker_for, parse_text, parse_file, walk_tree, parse_ratios, parse_ratios_file, ratios_placement +# internal_surface: marker and block matching helpers +# auth_boundary: none +# storage_boundary: read +# network_boundary: none +# user_data_boundary: read +# admin_only: false +# tests: tests/test_universal_parser.py +# rollout: exact-pinned reference parser propagation +# rollback: restore a previously accepted exact parser identity +# === END MODULE_BUILD === +# === CONTRACTS === +# id: msdmd_python_parser_preserves_field_names +# given: a valid metadata entry uses lowercase snake-case field names containing digits +# then: parsed entries retain those field names and string values without executing the inspected source +# class: evidence +# === END CONTRACTS === """Universal msdmd parser — pure stdlib. Implements the parser contract from ``msdmd/SKILL.md``: extracts every @@ -69,7 +92,7 @@ } _DEFAULT_SKIP = ( - "__pycache__", "node_modules", ".git", ".venv", "venv", + "__pycache__", "node_modules", ".git", ".agents", ".venv", "venv", "dist", "build", ".next", ".nuxt", "target", ".pytest_cache", ".mypy_cache", ".tox", ) @@ -100,7 +123,7 @@ def parse_text(text: str, block_name: str, marker: str = "#") -> list[dict]: block_re = _block_regex(block_name, marker) m = re.escape(marker) id_re = re.compile(rf"^\s*{m}\s*id:\s*(?P\S+)\s*$") - field_re = re.compile(rf"^\s*{m}\s+(?P[a-z_]+):\s*(?P.+?)\s*$") + field_re = re.compile(rf"^\s*{m}\s+(?P[a-z_][a-z0-9_]*):\s*(?P.+?)\s*$") entries: list[dict] = [] for block in block_re.finditer(text): @@ -189,7 +212,7 @@ def iter_source_files(path: Path) -> Iterable[Path]: # boundary to literal line 2: # ratios: loc_comments=N:M imports_exports=N:M calls_definitions=N:M RATIO_IDS = ("loc_comments", "imports_exports", "calls_definitions") -_RATIOS_TOKEN_RE = re.compile(r"(?P[a-z_]+)=(?P\S+)") +_RATIOS_TOKEN_RE = re.compile(r"(?P[a-z_][a-z0-9_]*)=(?P\S+)") def _ratios_line_re(marker: str) -> re.Pattern[str]: @@ -253,4 +276,4 @@ def ratios_placement(text: str, marker: str = "#") -> tuple[bool, bool]: last_ok = bool(line_re.match(raw.rstrip())) break return (opening_ok, last_ok) -# ratios: loc_comments=161:57 imports_exports=4:7 calls_definitions=55:10 +# ratios: loc_comments=161:80 imports_exports=4:7 calls_definitions=55:10 diff --git a/.agents/skills/msdmd/parsers/universal.ts b/.agents/skills/msdmd/parsers/universal.ts index 141f46c5..619e1a89 100644 --- a/.agents/skills/msdmd/parsers/universal.ts +++ b/.agents/skills/msdmd/parsers/universal.ts @@ -1,4 +1,27 @@ // ratios: loc_comments=hmmm imports_exports=hmmm calls_definitions=hmmm +// === MODULE_BUILD === +// id: msdmd_typescript_reference_parser +// module_name: universal +// module_kind: instrument +// summary: parses canonical line-comment metadata without executing inspected source +// owner: The Interdependency skill-lib +// public_surface: Entry, WalkOptions, COMMENT_MARKERS, RATIO_IDS, markerFor, parseText, parseFile, walkTree, parseRatios, parseRatiosFile, ratiosPlacement +// internal_surface: marker and block matching helpers +// auth_boundary: none +// storage_boundary: read +// network_boundary: none +// user_data_boundary: read +// admin_only: false +// tests: tests/test_universal_parser.py::test_typescript_parser_field_contract +// rollout: exact-pinned reference parser propagation +// rollback: restore a previously accepted exact parser identity +// === END MODULE_BUILD === +// === CONTRACTS === +// id: msdmd_typescript_parser_preserves_field_names +// given: a valid metadata entry uses lowercase snake-case field names containing digits +// then: parsed entries retain those field names and string values without executing the inspected source +// class: evidence +// === END CONTRACTS === /** * Universal msdmd parser — pure Node stdlib (fs, path). * @@ -61,7 +84,7 @@ export const COMMENT_MARKERS: Record = { }; const DEFAULT_SKIP = new Set([ - "__pycache__", "node_modules", ".git", ".venv", "venv", + "__pycache__", "node_modules", ".git", ".agents", ".venv", "venv", "dist", "build", ".next", ".nuxt", "target", ".pytest_cache", ".mypy_cache", ".tox", ]); @@ -86,7 +109,7 @@ export function parseText( "gm", ); const idRe = new RegExp(`^\\s*${m}\\s*id:\\s*(\\S+)\\s*$`); - const fieldRe = new RegExp(`^\\s*${m}\\s+([a-z_]+):\\s*(.+?)\\s*$`); + const fieldRe = new RegExp(`^\\s*${m}\\s+([a-z_][a-z0-9_]*):\\s*(.+?)\\s*$`); const entries: Entry[] = []; let match: RegExpExecArray | null; @@ -185,7 +208,7 @@ function ratiosLineRe(marker: string): RegExp { export function parseRatios(text: string, marker: string = "#"): Entry[] { const lineRe = ratiosLineRe(marker); - const tokenRe = /([a-z_]+)=(\S+)/g; + const tokenRe = /([a-z_][a-z0-9_]*)=(\S+)/g; const out: Entry[] = []; for (const raw of text.split("\n")) { const lm = lineRe.exec(raw.replace(/\s+$/, "")); diff --git a/.agents/skills/msdmd/references/metadata-conventions.md b/.agents/skills/msdmd/references/metadata-conventions.md new file mode 100644 index 00000000..151ba6d7 --- /dev/null +++ b/.agents/skills/msdmd/references/metadata-conventions.md @@ -0,0 +1,200 @@ +# Metadata conventions — discovery and extraction contract + +This reference extends `../SKILL.md`. Use it to inventory actual inputs, select +readers, and design tests. **The rows below specify what to inspect; they do not +claim that skill-lib ships readers for those conventions.** Resolve and record +an authoritative specification or owning implementation before interpreting a +particular dialect. A family name is not an implementation status. + +## Open-world coverage rule + +Any existing metadata convention encountered in the declared scan scope is an +eligible input. Include native and project-local conventions, custom tags, +extensions, older versions still present in inputs, and new formats not named +below. An unrecognized file remains in the discovery ledger; a recognized but +uninterpreted declaration retains its source reference and an unsupported or +opaque status. Do not claim that unknown syntax was fully detected or understood. + +"All conventions" means an open ingestion boundary with explicit accounting, +not a finite catalogue masquerading as universal parser coverage. Add a reader +contract when a new convention appears; do not require changes to its owner merely +to make the source fit MSDMD. Retired input syntax may be inspected as historical +data without being recommended for new authoring. + +## Convention catalogue + +### Language, symbol, and documentation metadata + +| Family | Explicit conventions and sources to inspect | Preservation / interpretation boundary | +|---|---|---| +| Python | PEP 257 docstrings; reStructuredText/Sphinx fields; Google-style and NumPy-style sections; signatures, annotations, type comments, `.pyi`, `Annotated`, decorators, dataclass/field declarations, `__all__`, encoding cookies, inline script metadata. | Separate each docstring dialect and typing version. Preserve expressions without importing modules, evaluating annotations, invoking decorators, or resolving dynamic exports by execution. | +| JavaScript / TypeScript | JSDoc, TSDoc, TypeDoc extensions; `.d.ts`; signatures, generics, interfaces, visibility, import/export declarations, decorators, compiler directives. | JSDoc, TSDoc, and TypeDoc are not interchangeable tag grammars. Keep unknown/custom tags, inline links, overloads, and declared versus inferred types. | +| C / C++ / Objective-C | Doxygen and HeaderDoc comments; declarations, attributes, pragmas, preprocessor conditions, include edges, compiler annotations. | Preserve active/unknown configuration branches. A textual include is not a resolved build dependency under every target. | +| Java / JVM | Javadoc including version-specific comment forms; annotations; `package-info.java`, `module-info.java`, signatures and modifiers; Kotlin KDoc and annotations; Scala Scaladoc and annotations; Groovydoc. | Preserve dialect, target, retention/visibility declarations, generics, and inheritance links. Do not run annotation processors or compile project code during static collection. | +| .NET | C#/VB/F# XML documentation; attributes; nullable/type metadata; assembly and project metadata. | Keep XML structure and `cref`/inheritance references. Disable external entity expansion. Do not infer runtime attribute effects from spelling alone. | +| Rust | rustdoc comments and attributes; `cfg`/`cfg_attr`, `deprecated`, visibility, signatures, traits and bounds; doctest flags. | Preserve feature/target conditions and macro invocations. An example or doctest flag is not a passing execution result. | +| Go | Go doc comments; declaration comments; struct tags; build constraints; `go:generate`, `go:embed`, and other versioned directives. | Preserve directive scope and tag namespaces. Never execute generation directives during extraction. | +| Swift / Apple | Documentation comments, DocC markup, attributes, availability declarations, Swift package and plist metadata. | Keep platform/version availability and symbol attachment; do not load package scripts to collect values. | +| Ruby / PHP | RDoc, YARD and tags; Ruby declaration/mixin syntax; PHPDoc, attributes, signatures and namespace declarations. | Distinguish documentation type claims from language syntax and dynamic metaprogramming. | +| BEAM | Elixir `@moduledoc`, `@doc`, `@typedoc`, `@spec`, `@type`, behaviours and attributes; Erlang EDoc and versioned documentation attributes/specs. | Treat expressions and macros as source data; preserve module/function/type scope without starting a runtime. | +| Lisp / functional | Clojure metadata maps, `^` metadata, docstrings, arglists; Common Lisp documentation forms; Scheme/Racket documentation; Haskell Haddock and pragmas; OCaml odoc. | Do not evaluate forms. Resolve syntax and metadata semantics from the identified language/tool, not a shared punctuation shape. | +| Scientific / statistical | R roxygen2, DESCRIPTION and NAMESPACE; Julia docstrings/macros; MATLAB help comments; Fortran documentation comments and declarations. | Resolve ambiguous extensions explicitly. Preserve language-specific binding and generated-source provenance. | +| Shell / operations | Interpreter shebangs; shell documentation conventions, ShellCheck directives; PowerShell comment-based help, attributes and parameter declarations; Perl POD; Lua LDoc/annotation dialects. | A shebang selects declared interpreter intent, not evidence of executable mode or installed availability. Keep positional requirements and never source the file. | +| Other languages | Dart doc comments/annotations; Zig doc comments; SQL comments and DDL metadata; Ada/SPARK aspects; HDL attributes; Prolog documentation; any additional language present. | Register exact syntax, ownership and tests before interpreting. Unsupported grammar remains visible; no language is silently discarded for lacking an MSDMD comment marker. | +| Ordinary and project-local comments | TODO/FIXME/XXX/HACK/NOTE markers; region markers; generated-file notices; project-defined structured comments; embedded Markdown, JSON, YAML, XML, or TOML. | Record literal markers and local interpretation separately. A TODO is not automatically a defect, assigned issue, or behavioral obligation. Comments inside strings/examples need syntax-aware discrimination. | + +### Repository, packaging, build, and operational metadata + +| Family | Explicit conventions and sources to inspect | Preservation / interpretation boundary | +|---|---|---| +| Python packaging | `pyproject.toml`, inline script metadata, `setup.cfg`, statically recoverable `setup.py`, core METADATA/PKG-INFO, entry points, requirements/constraints and lock formats. | Preserve specification version and declared dynamic fields. Build requirements, runtime requirements, extras, groups, constraints, and resolved packages are different relationships. No build backend execution. | +| JavaScript packaging | `package.json`, npm/yarn/pnpm/bun lockfiles, workspace definitions, exports/imports maps and engine constraints. | Keep peer/optional/dev/runtime dependency classes, environment conditions and resolution scope distinct. Scripts are declarations, not commands to run. | +| Other package ecosystems | Cargo manifests/locks; `go.mod`, `go.sum`, `go.work`; Maven POM, Gradle files/catalogues; NuGet/MSBuild/project files; Composer; Gemfile/gemspec/locks; Mix/rebar; Swift Package/CocoaPods; Dart pub; Julia Project/Manifest; R DESCRIPTION; OS package specifications. | Preserve package/workspace/target scope, constraints and resolutions. Executable configuration stays unresolved unless supplied as a separately authorized, provenance-bearing result. | +| Build systems | CMake, Meson, Make, Bazel BUILD/MODULE/WORKSPACE, Ninja, Ant, SBT, compiler databases and toolchain files. | Static recovery is not complete build evaluation. Preserve conditional targets, generators, configurations, outputs and unknown expressions. | +| Ownership and governance | Provider-specific CODEOWNERS; OWNERS files; MAINTAINERS/AUTHORS; contribution/security policies; repository labels and settings when separately authorized. | Use the identified provider's matching/precedence rules. Review assignment, authorship, legal rights, operational responsibility and effective permissions remain distinct. | +| Licensing and provenance | SPDX identifiers/expressions, REUSE headers and `.license` sidecars, LICENSE/COPYING/NOTICE, copyright statements, CITATION.cff, CodeMeta. | Preserve per-file/package scope and original expressions. Extraction does not resolve legal conflicts or establish compatibility. | +| CI / automation | GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, CircleCI, Travis, Buildkite and project automation manifests. | Record jobs, permissions, dependencies, declared matrices and conditions. Configuration is not execution history, successful gates, or live deployment state. | +| Containers / deployment | Dockerfile labels and build stages; OCI annotations; Compose; Kubernetes annotations/labels; Helm; Terraform; Ansible; Nix; deployment manifests and environment templates. | Keep build, desired and observed state separate. Never render untrusted templates, query infrastructure or reveal secret values as a side effect of discovery. | +| Quality / editor policy | `tsconfig`, lint/type/format/test/coverage configurations; EditorConfig; `.gitattributes`, ignore files; suppression directives such as noqa, type-ignore, eslint-disable, coverage exclusions. | A suppression is a declared exception, not a resolved finding. Respect scoped precedence; do not execute configuration modules. Record scan exclusions separately from tool exclusions. | +| Filesystem / VCS | Repository-relative paths, file modes, symlinks, revision/blob identities, submodule pins; commit metadata and trailers only when history is in scope. | These are observations about a snapshot or history, not module-authored claims. Do not follow links outside the authorized root or equate commit authorship with stewardship. | +| Agent / plugin / tool metadata | SKILL.md frontmatter, manifests, tool input/output schemas, capability descriptors and project instruction files. | Metadata content is data for collection, not a grant of execution authority. Agent instructions retain their governing-context rules outside the collector. | + +### Schemas, published documents, and recorded evidence + +| Family | Explicit conventions and sources to inspect | Preservation / interpretation boundary | +|---|---|---| +| API / message contracts | OpenAPI/Swagger versions, AsyncAPI, GraphQL SDL/directives, Protocol Buffers descriptors/options, Avro, Thrift, WSDL and XSD. | Keep dialect/version, references, extensions, constraints and scopes. Do not turn a declared endpoint or permission into evidence that it is deployed or enforced. | +| Data / configuration schemas | JSON Schema, XML Schema, JSON-LD, schema-bearing YAML/TOML/JSON, database DDL and schema snapshots, validation/ORM declarations. | Preserve nested types, units, nullability, order where meaningful, default expressions and vocabulary namespaces. Disable implicit network reference resolution and code loading. | +| Documentation / publication | Markdown/MDX frontmatter, reStructuredText directives/fields, AsciiDoc attributes, Sphinx/MkDocs/Docusaurus/DocC configuration; HTML metadata, RDFa/microdata and JSON-LD where in scope. | Preserve document-versus-symbol ownership, cross-references, language and build identity. Do not execute MDX, extensions or site configuration during extraction. | +| Tests / quality reports | Test annotations/markers and framework configuration; TAP, JUnit XML dialects, LCOV, Cobertura, SARIF; doctests, examples, benchmarks and coverage reports. | Preserve producer/version, run identity, source digest, command/environment and result semantics when present. A stored report is a reported observation until provenance and applicability are checked. | +| Supply chain / artifact evidence | SPDX/CycloneDX SBOMs, in-toto/SLSA attestations, signatures, package/distribution metadata and source maps. | A parsed signature is not a verified signature. Keep subject digests, issuer claims, validation results and source mappings distinct. No automatic download or trust promotion. | +| Data / notebook / model artifacts | Jupyter cell/notebook metadata, Arrow/Parquet schema metadata, HDF5 attributes, model cards/dataset cards and model-container metadata when explicitly in scope. | Use format-specific bounded readers. Do not execute notebooks, unpickle objects, load arbitrary model code, or expose sensitive datasets merely to inspect metadata. | +| Binary / archive metadata | ELF/PE/Mach-O, DWARF/PDB, JAR/class metadata, package archives and other artifact formats when explicitly in scope. | Optional isolated, size-bounded readers with exact tool identity; no executable loading or unsafe archive extraction. Unsupported binaries remain in the inventory rather than silently disappearing. | +| Unlisted convention | Any additional established or project-local convention found in the authorized scope. | Preserve source and uncertainty, resolve the owner/specification, register a reader and fixtures, then promote only the tested subset to supported. | + +## Reader contract + +Each actual reader must publish a machine-readable manifest containing: + +- `reader_id`, version or implementation digest, entry point, dependencies; +- convention namespace, specification/owning implementation reference and supported + versions, dialects, feature subset and known limitations; +- detection rules and ambiguity handling, plus configuration precedence; +- subject/scope attachment and native precedence rules; +- typed field mappings, relation meanings, raw-source preservation and unknown-field policy; +- invalid-input behavior, resource/disclosure limits and execution/network policy; +- positive, negative and adversarial fixtures with replayable results. + +Mark support as `implemented-and-tested`, `partial`, `specified-only`, or +`unsupported`, qualified by exact version and feature subset. An operational run +also reports `not-applicable`, `ambiguous`, `invalid`, `unreadable`, `excluded`, +`dynamic-unresolved` or other precise diagnostics as needed. These are different +axes: a supported reader can encounter invalid input; a specified reader is not +an available parser. Unmeasured usage maturity is not test evidence. + +Readers consume immutable bytes plus explicit parsing context and return facts, +source references and diagnostics. Do not impose a fictitious callable signature +on helpers that have not been implemented. Keep discovery, extraction, semantic +mapping, policy evaluation and execution evidence separate and composable. + +### Minimum native-capable fact shape + +The future versioned collection must be able to express: + +| Information | Requirement | +|---|---| +| Source identity | Repository/source authority, exact revision and blob/content digest; dirty-worktree identity when applicable. | +| Location | Relative path and exact span or structural pointer; references to additional source inputs for multi-source derivations. | +| Subject | Qualified subject address and scope: repository, workspace, package, target, file, module, symbol, parameter, document, run, or artifact as applicable. | +| Convention | Namespace, detected/declared version, dialect and any unresolved identification. | +| Native declaration | Native ID/key/tag/path when present; typed value/tree or an access-controlled raw source reference. Preserve repeats and unknown fields. | +| Projection | Optional canonical field/relation, mapping version, input references and declared information loss. | +| Epistemic standing | Declared, syntactically observed, derived, or reported evidence; independently verified status requires a linked verification receipt. | +| Extraction | Reader identity/version, effective configuration digest, feature coverage and diagnostics. | +| Provenance / conflicts | All source witnesses, source-local precedence, disagreement groups and explicit resolution rationale when any. | + +Do not serialize typed unknown values into invented string conventions such as +`"None"` or silently flatten arrays/maps. Distinguish absent fields, explicit null, +empty values, unresolved expressions, redaction and inaccessible sources. Never +invent source locations, native IDs, relationships or verification receipts. + +## Cross-skill consumption + +- **doc-build:** native descriptions, examples, parameter/return docs and links + can satisfy their corresponding documentation obligations. A present comment + does not automatically satisfy every public-surface documentation requirement. +- **cap-build / deps-build:** signatures, exports, API schemas, imports and + manifests provide declared surfaces and scoped dependency relationships. Full + behavioral capability and complete dynamic call graphs need separate evidence. +- **owner-build:** consume native ownership patterns and declarations with their + exact scope and provider semantics; unresolved mappings remain visible. +- **test-build:** native contracts/assertions, test markers and reports can supply + inputs where a tested mapping exists. Never invent `proves` links from names + or treat an example/marker as an executed witness. +- **meta-module-build / risk-boundary-build:** consume existing manifests and + permission/data-effect declarations before requesting missing design intent. + Declared risk controls are not verified enforcement. +- **manifest / llms-build / typed-meta-frontend:** consume native project metadata, + instructions and schemas without creating a second owning copy. Preserve + read-only fields, edit destinations and unresolved values. +- **ratios:** keep shebang position and existing seals intact. Measured ratios + retain their measurement method; native metadata does not imply those ratios + have been recomputed or checked. + +## Acceptance matrix + +These are required executable fixture cases for reader implementation, **not +results already obtained by editing the skill**. + +| Case | Required result | +|---|---| +| Native-only repository, zero MSDMD blocks | Exact supported metadata extraction; no fabricated declarations or false missing-information findings. | +| Truly absent required information | A scoped missing result after eligible sources and capable readers have been evaluated. | +| Native plus supplemental MSDMD | Complementary information composes without forced redeclaration; all provenance survives. | +| Conflicting descriptions or types | Preserve both, identify their distinct authority/scope, and expose unresolved disagreement. | +| Same symbol name in two packages / overloads | Qualified identities remain distinct; no accidental merging. | +| Unknown/custom tags and nested extensions | Preserve raw/typed source and namespaces; mark semantic mapping unknown rather than dropping it. | +| Unsupported language, dialect or version | Visible unsupported/ambiguous scope; neither absent nor complete. | +| Invalid, truncated or undecodable source | Parse/read diagnostic with source identity; no fabricated recovery success. | +| Dynamic metadata or executable configuration | Expression and unresolved status retained; application code is not executed. | +| Ownership precedence and unmatched paths | Correct provider-specific matching; unrelated author/reviewer/permission concepts are not collapsed. | +| Conditional imports / optional dependencies / target features | Conditions, dependency class and resolution uncertainty survive. | +| Comments inside strings, examples and generated outputs | No false declaration attachment or self-generated evidence loops. | +| Shebang / encoding / newline / source positions | Original boundaries and byte/source references preserved correctly. | +| Excluded, symlinked, missing and binary files | Full scope accounting; no traversal escape or silent denominator reduction. | +| Embedded commands, YAML tags, XML entities, remote references | No implicit code execution, unsafe object construction or network access. | +| Secret-bearing fields and private reports | Correct access controls/redaction with visible withheld scope; no secret leakage. | +| Stale test report / wrong commit / unverified signature | Keep reported evidence separate; reject unsupported verification promotion. | +| Deterministic replay and source change | Stable semantic output for identical pinned inputs; stale outputs invalidated when owning inputs change. | +| Legacy consumer cannot represent a native fact | Explicit schema incompatibility or labeled loss; no silent flattening. | +| Claimed reader support without passing fixtures | Reject the support claim; retain specified-only/partial/unsupported standing. | + +## Primary references + +Resolve the exact relevant version at reader implementation time. The following +sources were consulted for this skill revision on 2026-09-15; they establish +specific convention families, not implementation coverage of the catalogue. + +- Python docstrings: https://peps.python.org/pep-0257/ +- Google/NumPy docstring handling: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html +- Python project metadata, including version-sensitive dynamic rules: https://packaging.python.org/en/latest/specifications/pyproject-toml/ +- JSDoc: https://jsdoc.app/ +- TSDoc tag kinds: https://tsdoc.org/pages/spec/tag_kinds/ +- TypeScript JSDoc support: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html +- Doxygen comments: https://www.doxygen.nl/manual/docblocks.html +- Rust documentation tests: https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html +- Go doc comments: https://go.dev/doc/comment +- JDK 25 Javadoc: https://docs.oracle.com/en/java/javase/25/docs/specs/javadoc/doc-comment-spec.html +- C# XML documentation: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/ +- npm v11 package metadata: https://docs.npmjs.com/cli/v11/configuring-npm/package-json/ +- GitHub CODEOWNERS: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +- OpenAPI specifications: https://spec.openapis.org/oas/latest.html +- JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core +- SPDX specifications: https://spdx.dev/use/specifications/ +- SARIF 2.1.0: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html + +## hmmm + +Each implemented reader still needs its own exact-version authority, supported +feature list and executable receipts. This catalogue deliberately leaves new +conventions admissible. An open door is not a claim that everyone has arrived. diff --git a/.agents/skills/test-build/SKILL.md b/.agents/skills/test-build/SKILL.md index 1276ba44..bac18326 100644 --- a/.agents/skills/test-build/SKILL.md +++ b/.agents/skills/test-build/SKILL.md @@ -1,21 +1,35 @@ --- name: test-build -description: Self-declaring contract tests built on msdmd. Source modules own behavior obligations in `# === CONTRACTS ===` blocks; test modules own executable evidence in `# === CHECKS ===` blocks. Load this when adding tests that ride the msdmd convention, when refactoring a module with CONTRACTS/CHECKS declarations, or when authoring a contract/check audit or executor. +description: Native-first contract evidence built on msdmd. Source owners declare behavior obligations and test owners declare accountable witnesses through supported native conventions or supplemental CONTRACTS and CHECKS blocks. Preserve explicit claim linkage and no-exec audit boundaries. Load this when adding tests that use msdmd, refactoring CONTRACTS/CHECKS declarations, or authoring a contract/check audit or executor. --- # test-build — Contract tests on msdmd `test-build` is an application of [msdmd](../msdmd/SKILL.md). The -foundational skill defines the comment-block convention, the universal -parser, and the visible-gap requirement; this skill applies the -convention to behavior contracts and their executable witnesses. +foundation defines native-first ingestion, supplemental block syntax, reader +support and information coverage; this skill applies those contracts to +behavior obligations and accountable executable witnesses. -Read `msdmd/SKILL.md` first if you haven't — the block syntax, -parser contract, and visibility rules below are inherited from there -and not redefined. +Read `msdmd/SKILL.md` first. For the ratified source/test ownership split, +see [`doctrine/msdmd-checks.md`](../doctrine/msdmd-checks.md). -For the ratified doctrine behind this split, see -[`doctrine/msdmd-checks.md`](../doctrine/msdmd-checks.md). +## Native-first coverage + +Source-owned native contracts/assertions and test-owned witness declarations +may supply evidence-graph inputs through explicit, tested mappings. Keep each +obligation and witness attributable to its actual owner. A native witness needs +no CHECKS copy when the supported mapping provides the required linkage, +execution target and safety information. Test names, markers and examples alone +do not establish a `proves` relationship or a passing execution result. + +Native fields retain their own schemas; the block schemas below constrain +supplemental entries. They do not require native sources to manufacture MSDMD +IDs or strings. Preserve qualified source identities and unresolved mappings. + +Implementation status: the examples and bundled RepoLOTO audit/check path use +CONTRACTS/CHECKS blocks. Native contract/witness readers and a unified native +evidence reconciler are not shipped by this skill revision. A block-only audit +must disclose that scope, and cannot call required native scope complete. ## The split @@ -26,13 +40,13 @@ audit reconciles the witness list against the obligation list. ``` Source modules own promises. Test modules own evidence. Neither owns -the other's declarations. +the other's declarations. Native ingestion preserves this ownership split. ## Source block: CONTRACTS -Every module that promises behavior declares those obligations in a -`CONTRACTS` block. A contract says what must remain true; it does not -name the test topology. +Source owners declare promised behavior through supported native contracts or +supplemental `CONTRACTS` entries. A contract says what must remain true; it does +not name the test topology. Supplement unexpressed obligations as follows: ```python # === CONTRACTS === @@ -50,7 +64,7 @@ name the test topology. ### CONTRACTS field schema -Required: +Required for a supplemental CONTRACTS entry: | Field | Meaning | |---|---| @@ -68,13 +82,13 @@ Optional: | `deprecated` | If present, the runner skips and reports the entry as deprecated. | `call:` is not a CONTRACTS field in skill-lib. The call belongs to the -CHECKS entry that owns the executable evidence. +CHECKS entry or native witness that owns the executable evidence. ## Test block: CHECKS -A test module declares the checks it contributes in a `CHECKS` block. -A check is an evidentiary procedure: an executable claim to prove one -or more named contracts. +Use `CHECKS` for witness information not adequately expressed by a supported +native source. A check is an evidentiary procedure: an executable claim to prove +one or more named contracts. ```python # === CHECKS === @@ -98,7 +112,7 @@ or more named contracts. ### CHECKS field schema -Required: +Required for a supplemental CHECKS entry: | Field | Meaning | |---|---| @@ -121,28 +135,27 @@ as a defect, not diligence. ## The contract for check functions -A check function: +A check function in the block executor contract: - Is resolvable at the path declared in `call:`. - Takes no required arguments. The executor does not inject fixtures or context; the check is self-contained or pulls from the language's standard environment (env vars, a known service URL, etc.). - Returns `None` on pass. -- Raises `AssertionError` on behavior violation. The runner reports - this as `FAIL`. -- Lets unexpected exceptions escape. The runner reports these as - `ERROR` (infrastructure/harness failure) rather than `FAIL` - (contract violation). -- Cleans up any persistent state it creates. Isolation is the check's - responsibility unless the runner explicitly provides a fixture. +- Raises `AssertionError` on behavior violation. The runner reports `FAIL`. +- Lets unexpected exceptions escape. The runner reports `ERROR` + (infrastructure/harness failure), not `FAIL` (contract violation). +- Cleans up persistent state. Isolation belongs to the check unless the runner + explicitly supplies a fixture. + +A native framework adapter must separately declare its actual calling and +fixture conventions rather than pretending every native test has this shape. ## Authoring an audit -Audit is the cheapest runner mode: reconcile declarations without -executing checks. Resolve `self::fn` against the declaring file's -**parsed** function definitions — never by importing it or reading -loaded callables, since import executes module top level and an audit -that executes is not an audit: +Audit reconciles declarations without executing checks. Resolve `self::fn` +against the declaring file's **parsed** definitions — never by importing the +module, since importing executes its top level: ```python import ast @@ -164,12 +177,10 @@ def resolve_self_call(spec: str, defined: set[str]) -> str: return name ``` -(The bundled `tests/test_repo_loto.py` reads `globals()` instead — it -can, because its audit runs *as* that module, so its own `def`s are -already in scope. A central audit walking other test files has no such -shortcut and must parse, as above.) +The bundled `tests/test_repo_loto.py` may read `globals()` because its audit runs +as that module; a central audit of other test files has no such shortcut. -An audit MUST report, at minimum: +For an explicitly block-only audit, the existing diagnostics are: ```text GAP has no CHECKS entry claiming to prove it @@ -178,34 +189,37 @@ GAP call does not resolve: GAP executable check has no resolving CHECKS declaration ``` -Exit nonzero on any gap. A reconciler that has only ever said -"closed" is itself unverified; negative-test it by planting an orphan -contract, a phantom `proves` target, and an unresolvable call, then -observing the GAP. +A native-capable audit applies the same semantic obligations to supported native +witnesses as well. Missing CHECKS syntax alone is not missing evidence. Required +unsupported mappings are unresolved coverage and fail a strict audit; they must +not be reported as proof that no witness exists. + +Exit nonzero on genuine evidence gaps. Negative-test the audit with an orphan +contract, a phantom `proves` target and an unresolvable call. A reconciler that +has only ever reported closed is unverified. ## Authoring an executor -A full executor runs after audit or as part of the same command. It -should: +A full executor should: -1. Parse source `CONTRACTS` and test `CHECKS` using the msdmd parser. -2. Reconcile the graph before execution. +1. Extract supported native obligations/witnesses and parse supplemental + source `CONTRACTS` and test `CHECKS` using the msdmd parser. An existing + block-only executor must disclose its narrower scope. +2. Reconcile the evidence graph before execution; refuse required unresolved scope. 3. Refuse execution when consumed `requires` fields are unmet. 4. Apply consumed `timeout` fields to the actual spawned work. -5. Report per-check `PASS`, `FAIL`, and `ERROR` without aborting the - remaining checks on a single harness error. -6. Surface source contracts with no proving checks, checks proving - unknown contracts, and executable checks with no declaration. +5. Report per-check `PASS`, `FAIL` and `ERROR` without concealing harness failures. +6. Surface contracts without accountable witnesses, orphan witness claims and + tests lacking required linkage, without requiring duplicate native declarations. -The visibility-of-gaps requirement is mandatory per msdmd. Drop it and -the runner stops being a msdmd application. +The visibility-of-gaps requirement is mandatory per msdmd. Report information +and evidence coverage, supported extraction and block adoption separately. ## Semantics of "proves" `proves:` means claims-to-prove. Audit verifies linkage and call resolution. A passing check demonstrates the declared witness ran -successfully. It does not prove the check is sensitive to every -possible breakage of the contract. +successfully. It does not prove sensitivity to every possible breakage. Status vocabulary: @@ -217,34 +231,36 @@ Status vocabulary: Do not claim one rung above the evidence. +## Validation + +Native-only witness fixtures need explicit source-linked obligations, executable +targets and safety metadata, with no invented `proves` edges or CHECKS copies. +Pair these future reader tests with orphan, unsupported-reader, unsafe-import +and wrong-revision-report cases. Existing block audit fixtures remain required. + ## Anti-patterns -- **Contracts in test files instead of source files.** The contract - belongs to the module that promises the behavior; the test file owns - the check. -- **`call:` in CONTRACTS.** Source modules should not know test - topology. Put executable targets in CHECKS. -- **Executable tests with no CHECKS entry.** They may still run through - ad hoc tooling, but they are invisible to the msdmd evidence graph. -- **CHECKS proving unknown CONTRACTS.** This is an orphan witness; fix - the target id or declare the source contract. -- **Implementation-shaped ids.** `chat_create_returns_200` tells you - little; `chat_create_owner_isolation` tells you what's protected. -- **Importing during audit.** Python imports execute module top level. - Use no-exec resolution such as `self::fn`, or make import execution - an explicit non-audit mode. -- **Catching unexpected exceptions in the check to "make it pass".** - Let the exception escape so the runner can mark `ERROR` honestly. +- **Contracts in test files instead of source files.** The promise belongs to + its source owner; the test file owns the check. +- **`call:` in CONTRACTS.** Put executable targets with their accountable witnesses. +- **Executable tests with no CHECKS entry.** Do not label them untracked until + eligible native witness mappings have been inspected; missing required mapping + is unresolved coverage, not permission to invent evidence. +- **CHECKS proving unknown CONTRACTS.** Repair the orphan target or source obligation. +- **Implementation-shaped ids.** `chat_create_returns_200` says less about the + protected capability than `chat_create_owner_isolation`. +- **Importing during audit.** Use no-exec resolution or a separately authorized execution mode. +- **Catching unexpected exceptions to make a check pass.** Preserve `ERROR` honestly. ## Versioning -The `CONTRACTS` block name remains stable for source-owned -obligations. `CHECKS` is the paired test-owned evidence block. -Field additions are non-breaking only when they are additive and -consumed by a runner. Field renames or removals are breaking; bump the -major version and note the migration in the lib README. +The `CONTRACTS` block name remains stable for source-owned obligations. +`CHECKS` remains the paired test-owned evidence block. Field additions are +non-breaking only when additive and consumed by a runner; renames or removals +require a major version and migration note. Native schema migration is separate. hmmm -- The block type for harness/infrastructure tests that prove no product contract remains unnamed is still unsettled. -- Mutation-level verification is defined but not yet generalized across skills. -- Slow/flaky/quarantined states should enter only when a runner consumes them rather than as decorative labels. +- native contract/witness readers and qualified evidence identities remain implementation work +- the block type for harness tests that prove no product contract remains unsettled +- mutation-level verification is not yet generalized across skills +- slow/flaky/quarantined states need actual consumers before becoming schema fields diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3495e806..dee9fd44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,8 @@ jobs: tests/test_ucns_adapter.py \ tests/test_ucns_dependency.py \ tests/test_measurement.py \ - tests/test_shared_stack_contract.py + tests/test_shared_stack_contract.py \ + tests/test_audit_regressions.py - name: Prove transcript measurement survives absent UCNS run: | python - <<'PY' @@ -131,7 +132,8 @@ jobs: tests/test_multiwoz21_corpus.py \ tests/test_ucns_dependency.py \ tests/test_measurement.py \ - tests/test_shared_stack_contract.py + tests/test_shared_stack_contract.py \ + tests/test_audit_regressions.py - name: Prove exact word-gonol observations survive the complete stack run: | python - <<'PY' @@ -211,6 +213,8 @@ jobs: - name: Smoke-test installed base package run: | .wheel-venv/bin/python - <<'PY' + import os + os.chdir("/tmp") from importlib.metadata import version from importlib.resources import files import edcm @@ -220,6 +224,19 @@ jobs: assert callable(edcm.select_metapat_adapter) assert callable(edcm.build_result_contract) assert edcm.run_integrity_gate().passed is True + assert "/site-packages/" in edcm.__file__ + from edcm.measurement import compress + source = "A: Here is the plan.\nI cannot do this.\nB: Accepted." + parsed = edcm.parse_transcript(source) + restored, _ = compress.from_bytes(compress.to_bytes(parsed)) + assert restored.source_text == source + assert "I cannot do this." in restored.turns[0].text + try: + edcm.build_default_layers().run({"rounds": []}) + except ValueError: + pass + else: + raise AssertionError("caller output accepted") assert files("edcm.measurement.canon").joinpath("data", "markers_v1.json").is_file() corpus_data = files("edcm.corpora").joinpath("data") assert corpus_data.joinpath("multiwoz_2_1_admission.json").is_file() diff --git a/.github/workflows/skill-compliance.yml b/.github/workflows/skill-compliance.yml index 96773e66..b05a57d2 100644 --- a/.github/workflows/skill-compliance.yml +++ b/.github/workflows/skill-compliance.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v7.0.1 with: repository: The-Interdependency/skill-lib - ref: c14ee9d500579a4b5d6821f62c9d82ca96e73608 + ref: dd5027d99516831c0dcb83a176a67140d3819b66 path: skill-lib - name: Check vendored subset byte-for-byte @@ -31,7 +31,7 @@ jobs: run: | python tools/check_consumer_drift.py ../edcm \ --canon-root . \ - --sha c14ee9d500579a4b5d6821f62c9d82ca96e73608 \ + --sha dd5027d99516831c0dcb83a176a67140d3819b66 \ --strict-sha \ --require-vendored @@ -48,7 +48,7 @@ jobs: uses: actions/checkout@v7.0.1 with: repository: The-Interdependency/skill-lib - ref: c14ee9d500579a4b5d6821f62c9d82ca96e73608 + ref: dd5027d99516831c0dcb83a176a67140d3819b66 path: skill-lib - name: Set up Python diff --git a/AGENTS.md b/AGENTS.md index 733f317b..559795be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,84 +1,73 @@ name: edcm description: | - Energy–Dissonance Circuit Model research, text-gonol construction, and measurement repository. Preserve the frozen maintained baseline as a candidate, keep METAPAT affixiation semantics / UCNS geometry / EDCM text construction distinct, run the exact UCNS–EDCM experiment graph, and never transfer proof, empirical validity, or canon status across repository boundaries. + Energy–Dissonance Circuit Model measurement and evaluation. Preserve exact source, + typed absence, candidate status, historical evidence and cross-repository authority. # === LLMS === -# id: edcm_agent_overview -# content: EDCM has a frozen maintained measurement baseline, an experiment-first UCNS–EDCM research surface, and the active text-domain gonol construction boundary. METAPAT owns affixiation semantics; UCNS owns gonol/Möbius/Public Gonol geometry and geometrically established operations; EDCM owns text-domain admission and linguistic/semantic gonol construction, including the rule that every admitted character is a gonol. Construction does not activate measurement. The baseline is candidate edcm-measurement-v1, not automatic joint canon. Preserve NA != 0 and all semantic/geometry/construction/measurement non-transfer boundaries. +# id: project_overview +# content: EDCM owns measurement/evaluation only. Package 0.2.0 supplies candidate edcm-measurement-v2, result schema 2.0.0 and codec 2. Frozen v1 canon data and historical reports retain their exact identities. UCNS owns gonol objects, constructors and geometry; Stack owns active language construction; METAPAT owns its semantic contracts. No proof or empirical status transfers. # -# id: edcm_agent_usage -# content: Read CANON.md, docs/GONOL_LANGUAGE_BOUNDARY.md, .agents/skills/gonol-build/SKILL.md, README.md, docs/UCNS_EDCM_EXPERIMENT_PROGRAM.md, CLAUDE.md, and the applicable organization skills before editing. For text-gonol work start in EDCM, consume current METAPAT affixiation invariants and current UCNS geometry, keep unresolved geometric operations hmmm, and independently replay claimed completed constructions. For joint measurements freeze the EDCM projection and falsifier separately. +# id: usage_rules +# content: Read CANON.md, CLAUDE.md, docs/GONOL_LANGUAGE_BOUNDARY.md and docs/migrations/0.2.0-audit-repair.md. Submit raw inputs to build_default_layers().run(); output-only and retired inputs fail closed. For active language construction start in the owning Stack workspace using UCNS constructors. Historical replay uses exact original EDCM and producer commits. Preserve NA != 0 and unresolved hmmm. +# +# id: architecture_summary +# content: The public pipeline validates raw inputs, selects independent METAPAT and UCNS adapters, measures transcripts with edcm.measurement, and assembles a complete hashed result. Optional absence is typed. UCNS geometry and factorization remain NA. Current language construction belongs to Stack/UCNS; retained EDCM construction modules serve historical replay. +# +# id: key_definitions +# NA: Required evidence, context, geometry, or authority is unavailable; never numeric zero +# hmmm: An unresolved constraint carried forward rather than guessed # === END LLMS === # EDCM agent entrypoint ## Read first -1. `CANON.md` -2. `docs/GONOL_LANGUAGE_BOUNDARY.md` -3. `.agents/skills/gonol-build/SKILL.md` for gonol, character, word, definition, recursive-relation, or affixiation work -4. `README.md` -5. `docs/UCNS_EDCM_EXPERIMENT_PROGRAM.md` -6. `CLAUDE.md` -7. `.agents/skills/the-interdependency/SKILL.md` -8. `.agents/skills/msdmd/SKILL.md` -9. `.agents/skills/meta-module-build/SKILL.md` -10. `.agents/skills/test-build/SKILL.md` -11. `.agents/skills/canon/SKILL.md` -12. `.agents/skills/interdependent-work-graph/SKILL.md` for cross-repository work -13. `docs/integrity-gates.md` -14. the exact historical UCNS source named by a historical experiment when replaying it -15. the source module's `MODULE_BUILD` block and its named tests - -## Authority boundaries - -```text -METAPAT affixiation semantics: The-Interdependency/metapat at the current governing commit -UCNS gonol geometry: The-Interdependency/ucns at the current governing or experiment-pinned commit -EDCM text construction: The-Interdependency/edcm current canon/profile -EDCM baseline measurement: The-Interdependency/edcm:edcm/measurement -organization skills: The-Interdependency/skill-lib@a1c6a7124af537ee9937b6fc6084940091982fe5 -experiment evidence: exact report, corpus, candidate, and workflow identities -``` - -Repository boundaries are authority and provenance boundaries, not isolated-agent boundaries. - -For active EDCM text construction: - -```text -every admitted character is a gonol -``` - -EDCM owns the character-admission profile and linguistic/semantic construction. UCNS owns the geometry used to realize admitted gonols. METAPAT owns the meaning of affixiation. Do not move either semantic authority into UCNS merely because UCNS supplies the carrier. - -## Current status - -- `edcm/measurement/` is the frozen maintained baseline candidate. -- `edcm.ucns_edcm_experiments` is the first joint experiment runner. -- EDCM owns current text-domain gonol admission and construction; measurement remains separately frozen and evaluated. -- `edcm.gonol` is the implemented candidate constructor for closing gonols through declared scale option sets. None is selected canon. -- UCNS structural policies, product-character candidates, faithful-breadth candidates, and unresolved Möbius coupling laws remain noncanonical unless current UCNS authority says otherwise. -- EDCM axes, thresholds, marker lists, and circuit parameters remain candidates unless an explicit canon decision says otherwise. -- A passing hypothesis is experiment-supported evidence, not canon. -- A failed hypothesis remains evidence and must not be removed to make the report look successful. - -## Required joint experiment validation +1. `CANON.md`, `README.md`, and `CLAUDE.md`. +2. `docs/migrations/0.2.0-audit-repair.md` and `docs/integrity-gates.md`. +3. `docs/GONOL_LANGUAGE_BOUNDARY.md` for construction/evaluation routing. +4. Current canonical skill-lib entrypoint and applicable skills; vendored copies + are consumers, pinned at `dd5027d99516831c0dcb83a176a67140d3819b66`. +5. The owning module's declarations and named tests before changes. +6. `docs/UCNS_EDCM_EXPERIMENT_PROGRAM.md` and exact historical producer sources + when replaying historical experiments. + +## Authority + +| Owner | Responsibility | +|---|---| +| METAPAT | Its semantic contracts and affixiation meaning | +| UCNS | Gonol objects, constructors, and geometry | +| Stack | Active language-gonol construction research and source/admission profiles | +| EDCM | Measurement/evaluation only | +| skill-lib | Organization build and evidence discipline | + +For new construction use [Stack English](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/english-gonol) +or [Stack Python](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/python-gonol). +Resolve current owning commits before new work. EDCM’s retained `edcm.gonol` and `edcm.language` +modules are historical replay surfaces, not active construction authority. -```bash -python -m pip install -e .[dev,ucns-experiments] -python tools/check_metadata_contracts.py -python -m pytest -q tests/test_ucns_edcm_experiments.py -python -m edcm.ucns_edcm_experiments --ucns-source-root /path/to/ucns-checkout --output artifacts/ucns-edcm-report.json -python -m edcm.ucns_edcm_experiments --ucns-source-root /path/to/ucns-checkout --output artifacts/ucns-edcm-report-repeat.json -diff -u artifacts/ucns-edcm-report.json artifacts/ucns-edcm-report-repeat.json -``` - -Historical runners use the exact UCNS commit they declare; do not silently repin historical evidence to current UCNS. +## Non-negotiable boundaries -## Required baseline validation +- `NA != 0`. +- Preserve source text, order, multiplicity, provenance and declared information loss. +- Public pipeline inputs cannot supply derived readouts, provenance or attachments. +- Missing geometry stays `NA`; an unresolved UCNS operation stays `hmmm`. +- Construction reproducibility does not establish measurement validity. +- UCNS or METAPAT proof/status does not validate EDCM readouts; EDCM fit does + not prove their mathematics or semantics. +- Candidate registration, fixture success or majority agreement does not select canon. +- Transcript measurements do not establish diagnosis, intention, morality, + consciousness or external truth. +- Frozen `*_v1.json` files change only by versioned canon migration. The 0.2 + implementation migration does not alter their byte identities. +- Historical reports remain immutable. Replay requires their exact original + EDCM and upstream source commits; current v2 output is new evidence. +- New modules and changed native modules declare real tests, boundaries and usage. + +## Validation and usage guidance ```bash -python -m pip install -e .[dev] +python -m pip install -e '.[dev]' python -m edcm.integrity python -m pytest -q python tools/check_metadata_contracts.py @@ -86,28 +75,20 @@ python -m build python -m twine check dist/* ``` -## Non-negotiable boundaries - -- `NA != 0`. -- every admitted character is a gonol for active EDCM text construction. -- METAPAT defines affixiation; EDCM applies it; UCNS realizes its geometry where constructed. -- represented evidence != constructed representation != candidate-measured evidence != experiment-supported evidence != canonically measured evidence. -- UCNS proof or theorem status does not validate EDCM readouts. -- EDCM empirical fit does not prove UCNS mathematics. -- METAPAT labels are authority constraints, not calculated EDCM values. -- package availability alone attaches no evidence. -- unresolved UCNS geometric operation remains `hmmm`; do not infer it from Unicode names, dictionary definitions, glyph shape, adjacency, or conventional grammar. -- no structural policy, support assignment, comparison policy, EDCM axis, `M`, or `B` becomes canonical by registration, majority, convenience, or development-fixture success. -- exact turn order, multiplicity, sidedness, source bytes, candidate identity, and information loss must remain recoverable. -- transcript-derived claims may not be expanded into diagnosis, intention, morality, consciousness, or external truth. -- new EDCM-native modules require accurate `MODULE_BUILD` metadata, usage guidance, and real test references. +Use a separate environment with `.[dev,full-stack]` for the exact optional +producer gates. Historical joint experiment epochs use `.[dev,ucns-experiments]` +and the exact source checkout named by their runner; never silently repin them. -## Usage guidance +For measurement: -For new text-gonol construction, begin in EDCM. Resolve the exact EDCM source/admission profile, import METAPAT affixiation invariants without redefining them, consume current UCNS geometry where normally available, and close gonols with `edcm.gonol` scale option sets. Once closed, a gonol is atomic at any scale; admissible larger-scale construction may consume closed gonols directly without reopening. Replay independently before claiming completion. Freeze any EDCM measurement only after construction and keep its evidence status separate. - -For historical experiments, reproduce the exact historical producer epoch and names. Historical UCNS-owned lexical artifacts remain evidence; they do not restore current language authority to UCNS. +```python +from edcm import build_default_layers +result = build_default_layers().run({"transcript": "A: State the condition.\nB: Recorded."}) +assert result["edcm_result"]["schema_version"] == "2.0.0" +``` ## hmmm -The exact character-admission unit remains profile-specific where not selected. The source-supported complete English morphology law, the exact UCNS Möbius-carrier affixiation/coupling law, direct distant-scale coupling geometry, EDCM measurement projection for recursive text gonols, external holdout custody, independent replication, human outcome-label authority, signed producer records, and the procedure for the first UCNS–EDCM canon decision remain unresolved. +General construct validity, independent outcome labels and holdout custody, +external replication, lawful projections over completed Stack constructions, +and signed producer authentication remain unresolved. See `docs/UPGRADE_AVENUES.md`. diff --git a/CANON.md b/CANON.md index 53c67e70..569798fa 100644 --- a/CANON.md +++ b/CANON.md @@ -12,7 +12,7 @@ Neither repository determines the joint canon alone: - UCNS structure or proof status does not validate an EDCM readout; - EDCM empirical fit does not prove a UCNS theorem or make a UCNS candidate canonical; -- the present `edcm.measurement` package is a frozen **baseline candidate**, not the final joint canon; +- the maintained `edcm.measurement` package is **candidate v2**, with historical v1 evidence preserved, not the final joint canon; - a candidate becomes `ucns-edcm` canon only through an explicit evidence-bearing decision packet after development and holdout experiments. ## The loop @@ -29,46 +29,20 @@ This reciprocal loop is the intended meaning of **UCNS–EDCM canon**. ## Gonol language boundary -The prior **lexical-floor** construction is DEPRECATED as current architecture. Historical artifacts keep their exact names and producer epochs for replay; they do not govern new text construction. +The current authority split is: -The active authority split is: +| Owner | Responsibility | +|---|---| +| METAPAT | Affixiation semantics and relational-integration invariants | +| UCNS | Gonol objects, constructors, and geometry | +| Stack | Active language-gonol construction research and source/admission profiles | +| EDCM | Measurement/evaluation only | -```text -METAPAT - affixiation semantics and relational-integration invariants - ↓ -UCNS - gonol geometry, native Möbius/Public Gonol carrier, - geometrically established operations - ↓ -EDCM - text-domain admission and linguistic/semantic gonol construction - ↓ -EDCM measurement - separately frozen projections, metrics, and falsifiers -``` - -For active EDCM text construction: - -```text -every admitted character is a gonol -``` - -This is an EDCM text-domain rule. EDCM owns the declared source/profile that determines what is admitted as a character. If a construction has not yet selected its exact unit—Unicode code point, grapheme, Public Gonol glyph inventory, or another explicit unit—that admission boundary remains `hmmm`. UCNS may realize admitted characters geometrically; UCNS does not own the linguistic admission rule merely because it owns the geometry. - -Current EDCM text construction uses declared scale option sets rather than a mandatory adjacent-scale ladder. `edcm.gonol` is the implemented candidate constructor for closing one gonol through a declared scale option set. Admissible scales may include character, word, suffix, suffix-coupling, definition, recursive relation, morphology, punctuation-function, source-specific, or later named scales when the governing construction declares their options. - -Once closed, a gonol is atomic at any scale. Closed gonols may participate directly at any admissible scale without reopening, while identity, order, multiplicity, source positions, relation identity, and provenance remain recoverable. Suffix-coupling exceptions are carried by the closed suffix gonol, such as `ing` carrying `suffix-coupling.final-y-after-consonant = preserve-y`, rather than by a global morphology law. Historical morphology evidence remains historical; the complete English morphology law remains `hmmm`. +For new language construction, start in [Stack English](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/english-gonol) or [Stack Python](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/python-gonol), consuming UCNS constructors and geometry. These source links pin the authority comparison used for this repair; resolve current owning commits before new research. -Affixiation is defined by METAPAT, not by EDCM and not by UCNS. EDCM applies affixiation to text-domain gonols. UCNS owns any exact geometric realization on the native Möbius/Public Gonol carrier. An unresolved UCNS coupling law remains `hmmm`; neither EDCM nor UCNS may fill it by importing an invented carrier, topology, scale increment, arity rule, containment rule, or linguistic convention. +Historical `edcm.gonol`, `edcm.language`, lexical-floor and sealed profile artifacts remain explicit replay surfaces. They confer no active construction authority on EDCM. There is no universal mandatory adjacent-scale ladder. Construction reproducibility does not validate EDCM measurement; an unresolved UCNS operation remains `hmmm`. -The replacement path does not insert conventional NLP token IDs, subword IDs, opaque external embedding vectors, or whole-string cryptographic hashes. Source prose, dictionaries, corpora, annotations, and labels may remain source evidence and provenance; they become gonol semantics only through an explicit EDCM construction whose admission, relation, closure, and replay boundaries are declared. - -UCNS Public Gonol function positions may be used by EDCM only to the extent their operations are geometrically established. Unicode names, dictionary definitions, glyph shape, adjacency, or conventional punctuation grammar do not define a UCNS operation. An unresolved operation remains `hmmm`. - -EDCM construction and EDCM measurement remain separate. A completed gonol construction does not activate measurement. Any scalar projection or measurement must separately declare its mapping, information loss, metric, aggregation, baseline, partitions, stopping rules, and falsifiers. UCNS geometry does not validate EDCM measurement; EDCM outcomes do not validate UCNS geometry or METAPAT semantics. - -See [`docs/GONOL_LANGUAGE_BOUNDARY.md`](docs/GONOL_LANGUAGE_BOUNDARY.md). +See [the language boundary](docs/GONOL_LANGUAGE_BOUNDARY.md) and [the 0.2 migration](docs/migrations/0.2.0-audit-repair.md). ## Evidence states @@ -132,21 +106,9 @@ Each generation preserves its own report identity and falsifiers. Later programs ## Baseline candidate -The maintained `edcm.measurement` implementation remains frozen as: - -```text -candidate: edcm-measurement-v1 -source: The-Interdependency/edcm:edcm/measurement -standing: historical maintained baseline, not joint canon -``` +The current measurement implementation is `edcm-measurement-v2` (package 0.2.0). Its v1 marker canon and equations are unchanged. Transcript intake, result contracts and codec fidelity changed under the [versioned migration](docs/migrations/0.2.0-audit-repair.md). -Its marker canon, parser, eleven-component round vector, and circuit recurrence remain available for comparison. Existing integrity gates preserve its identity; they do not confer empirical validity. - -The booking-outcome holdout adds a versioned calibration and operating -threshold for one narrowly scoped source action outcome. Those fitted values -belong to `edcm.maintained-terminal-progress/0.1.0`; they do not alter the -maintained baseline equations, define a default production threshold, or -become joint canon. +Candidate `edcm-measurement-v1` remains historical, bound to its original source commits, reports and falsification records. The historical booking-outcome calibration belongs to `edcm.maintained-terminal-progress/0.1.0`; the current runner identifies itself as `/0.2.0`. Historical fitted values are not production defaults or validation of the new parser. ## Compiled mathematical reference @@ -189,17 +151,7 @@ Where discourse graphs are involved, the experiment must additionally retain: - a canonical bundle identity across alternatives; - information loss for every graph projection. -For new text-gonol or language-semantic experiments, the experiment must additionally retain: - -- the exact EDCM source artifact and character-admission profile; -- the current METAPAT affixiation authority identity when affixiation is used; -- the exact UCNS geometry/carrier identity used by the construction; -- EDCM construction code/profile and completion-receipt identities; -- constituent identity, order, multiplicity, occurrence position, relation identity, scale, source, and provenance; -- explicit failure on tokenizer, subword, opaque-vector, or whole-string-hash substitution for gonol identity; -- unresolved UCNS geometric operations as `hmmm`, not semantic inference; -- the EDCM measurement projection and declared information loss separately from EDCM construction; and -- preregistered comparison criteria before semantic or downstream outcome inspection when the criterion could be outcome-selected. +For evaluation of language-gonol outputs, retain the exact Stack construction workspace and receipt, UCNS constructor/geometry identity, source/admission profile, constituent identity/order/multiplicity/provenance, and unresolved operations. Freeze the EDCM projection, information loss, metrics, partitions, comparisons and falsifiers separately before outcome inspection. EDCM does not define the source construction. Historical lexical-floor artifacts may be reproduced against their original exact inputs, but their historical UCNS producer boundaries and fixed-list criteria are not forward experiment requirements. @@ -235,8 +187,7 @@ This phase may implement: - positive unresolved-reference and alternative-bundle evidence; - reproducible reports and policy-preservation findings; - CI execution against exact UCNS commits where experiments require them; -- source-bound EDCM gonol candidate construction through declared scale option sets under the current authority split; -- candidate UCNS Möbius-carrier realizations of affixiation under fixed METAPAT invariants; and +- source-bound evaluation of completed Stack constructions consuming UCNS constructors and geometry; and - preregistered EDCM measurements of completed text-gonol constructions. This phase may not promote: @@ -247,7 +198,7 @@ This phase may not promote: - canonical product character `M`; - canonical faithful breadth `B`; - canonical discourse resolver, relation vocabulary, or graph precedence; -- arbitrary dictionary prose into completed gonol semantics without an explicit EDCM construction; +- arbitrary dictionary prose into completed gonol semantics without an explicit construction from its owning Stack workspace; - the deprecated NGSL closed-floor rule into current text construction; - a tokenizer, subword vocabulary, opaque vector lookup, or whole-string hash into the gonol-native language path; - gonol semantic-role analogy into a claim of embedding replacement efficacy; @@ -268,8 +219,8 @@ python -m edcm.ucns_edcm_experiments_v4 \ Every report is research evidence. No report is a canon file, and no report may be renamed or imported as one. -For new text-gonol work, start in EDCM: resolve the EDCM source/admission profile, import current METAPAT affixiation invariants, supply explicit current UCNS geometry authority when geometry is claimed, construct and replay the EDCM gonols, and freeze any measurement separately. Do not move language semantics back into UCNS merely because UCNS supplies the carrier geometry. +For new construction use the owning Stack workspace and UCNS constructors. Freeze EDCM measurement separately. Historical replay requires the exact EDCM and UCNS commits; current runners label the new measurement candidate explicitly. ## hmmm -The exact EDCM character-admission unit remains source/profile-specific where not yet selected. The source-supported complete English morphology law remains unresolved. UCNS still has to expose the exact native Möbius-carrier affixiation/coupling law and direct distant-scale coupling geometry through implementation rather than semantic inference. EDCM has not yet selected a lawful projection, information-loss account, metric, benchmark, or falsifier for evaluating a completed recursive text-gonol representation. External holdout custody, independently authored graph annotations, human outcome labels, multilingual evidence, separate implementation replication, and the authority procedure for the first joint canon selection also remain open. +Language admission remains owned by the declared Stack source/profile. The source-supported complete English morphology law remains unresolved. UCNS still has to expose the exact native Möbius-carrier affixiation/coupling law and direct distant-scale coupling geometry through implementation rather than semantic inference. EDCM has not yet selected a lawful projection, information-loss account, metric, benchmark, or falsifier for evaluating a completed recursive text-gonol representation. External holdout custody, independently authored graph annotations, human outcome labels, multilingual evidence, separate implementation replication, and the authority procedure for the first joint canon selection also remain open. diff --git a/CLAUDE.md b/CLAUDE.md index 06b1388c..c2facf9d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,7 +27,7 @@ Unknown or unresolved facts are written `hmmm`, not guessed. Current `CANON.md` | Base runtime dependencies | none | | Optional integrations | pinned `ucns`, `metapat`, `full-stack` extras | | Build metadata | `pyproject.toml` | -| Package version | `edcm.__version__` | +| Package version | `edcm.__version__` (0.2.0) | | License | MPL-2.0 | | Tests | `pytest` | | CI | `.github/workflows/ci.yml` | @@ -81,35 +81,20 @@ Direct absence of `metapat` is typed unavailability. Transitive import errors, m ## Gonol-native language architecture -The active authority split is: +The current authority split is: -```text -METAPAT -> affixiation semantics and relational-integration invariants -UCNS -> gonol geometry, native Möbius/Public Gonol carrier, - geometrically established operations -EDCM -> text-domain admission and linguistic/semantic gonol construction -EDCM -> separately declared measurement projections and falsifiers -``` - -For active EDCM text construction: - -```text -every admitted character is a gonol -``` - -This is an EDCM text-domain rule. EDCM owns the source/profile that decides what is admitted as a character. If a profile has not selected Unicode code point, grapheme, exact Public Gonol glyph inventory, or another explicit unit, that admission boundary remains `hmmm`; UCNS does not silently decide it merely because UCNS supplies the geometry. - -Active construction uses declared scale option sets rather than a mandatory adjacent-scale ladder. `edcm.gonol` is the implemented candidate constructor for closing one gonol at a declared scale. Once closed, a gonol is atomic at any scale; do not reopen a completed gonol or invent UCNS coupling geometry. - -Do not insert a conventional NLP tokenizer, token IDs, subword pieces, opaque external vector lookup, or whole-string hash as a substitute for gonol identity. Source prose, dictionaries, corpora, labels, and annotations may remain evidence and provenance; they become gonol semantics only through a source-bound EDCM construction whose admission, relation, closure, and replay boundaries are explicit. - -Affixiation is defined by METAPAT. UCNS owns any exact geometric realization of the operation. EDCM applies it to text-domain gonols. Linguistic prefixes and suffixes are one instance; they do not define affixiation. +| Owner | Responsibility | +|---|---| +| METAPAT | Affixiation semantics and relational-integration invariants | +| UCNS | Gonol objects, constructors, and geometry | +| Stack | Active language-gonol construction research and source/admission profiles | +| EDCM | Measurement/evaluation only | -Do not invent an alternative carrier, topology, scale increment, arity rule, containment rule, or coupling law to fill unresolved UCNS geometry. Implement the native Möbius/Public Gonol carrier under the fixed contracts and preserve missing geometric law as `hmmm` until construction exposes it. +For new language construction, start in [Stack English](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/english-gonol) or [Stack Python](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/python-gonol), consuming UCNS constructors and geometry. These source links pin the authority comparison used for this repair; resolve current owning commits before new research. -UCNS owns the geometry of Public Gonol function positions. EDCM may use only operations that current UCNS geometry actually establishes. Unicode names, dictionary definitions, conventional punctuation grammar, adjacency, and glyph shape do not supply UCNS function authority. An unresolved operation remains `hmmm`. +Historical `edcm.gonol`, `edcm.language`, lexical-floor and sealed profile artifacts remain explicit replay surfaces. They confer no active construction authority on EDCM. There is no universal mandatory adjacent-scale ladder. Construction reproducibility does not validate EDCM measurement; an unresolved UCNS operation remains `hmmm`. -A completed EDCM gonol construction does not activate EDCM measurement. Any later projection must separately declare information loss, metric, aggregation, baseline, partitions, stopping rules, and falsifiers. Construction reproducibility does not establish semantic quality, embedding equivalence, compression advantage, cognition, consciousness, or measurement validity. +See [the language boundary](docs/GONOL_LANGUAGE_BOUNDARY.md) and [the 0.2 migration](docs/migrations/0.2.0-audit-repair.md). ## Exact EDCM UCNS observation profile @@ -205,7 +190,7 @@ composition delivery ``` -Every supported pipeline result includes `edcm_result` schema `edcm.shared-stack-result/1.2.0` with: +Every supported pipeline result includes `edcm_result` schema `edcm.shared-stack-result/2.0.0` with: ```text source_evidence @@ -231,7 +216,7 @@ observations, readouts, independently attached evidence, and attachment states. turns are EDCM objects. They are not substitutes for formal UCNS geometry. Keep source evidence, METAPAT semantic authority, UCNS profile observations, -UCNS geometry identity, UCNS status evidence, EDCM text-construction identity, +UCNS geometry identity, UCNS status evidence, Stack construction identity, EDCM policy identity, and EDCM readouts separate. UCNS equality does not imply EDCM measurement equivalence. UCNS or METAPAT theorem/domain/certification status is attached evidence only and never promotes EDCM empirical validity. @@ -247,15 +232,14 @@ proof_status_transfers_to_measurement_validity = false ## Non-negotiable guardrails - `NA != 0`. -- For active EDCM text construction, every admitted character is a gonol. -- METAPAT owns affixiation semantics; UCNS owns geometry; EDCM owns text-domain admission and linguistic/semantic construction. +- METAPAT owns affixiation semantics; UCNS owns gonol objects, constructors and geometry; Stack owns active language construction; EDCM owns measurement/evaluation only. - No-bone, empty-field, absent-adapter, missing-context, and absent-evidence cases remain typed absence or `NA`. - Ordered windows compose with `SeqAppend`; never average testimony-bearing order. - METAPAT semantic labels never become measured values merely by being named. - Deterministic transcript metrics do not establish diagnosis, intent, consciousness, external truth, or root ontology. - UCNS observation digests establish content identity, not signed producer authentication. - Historical `token`, `word-gonol`, lexical-floor, or UCNS producer vocabulary never authorizes a tokenizer or overrides the current EDCM gonol-language boundary. -- Source prose or dictionary text never substitutes for an explicit source-bound EDCM gonol construction. +- Source prose or dictionary text never substitutes for an explicit source-bound construction from the owning Stack workspace. - Unicode names, dictionary definitions, adjacency, conventional grammar, and glyph shape never fill unresolved UCNS function geometry. - Unresolved geometry remains `hmmm`; do not invent a different carrier or scale law to make the pipeline complete. @@ -284,7 +268,7 @@ The historical UCNS profile suite must prove: - package availability alone attaches no observation; - profile evidence never becomes geometry, factorization, theorem, or measurement validity. -A current text-gonol construction suite must additionally prove the active EDCM source/admission profile, the rule that every admitted character is a gonol, participant/occurrence/order/multiplicity/provenance preservation, intrinsic relation capture, closure and atomic-participation boundaries, exact UCNS geometry identity where used, unresolved geometric operations remaining `hmmm`, complete-source execution for completion claims, and independent replay. It must fail closed on tokenizer IDs, subwords, opaque-vector substitution, whole-string-hash substitution, invented morphology, and semantic inference standing in for unresolved UCNS geometry. +EDCM evaluations consume completed constructions with exact source identities, order, multiplicity, provenance and declared losses. Construction and replay gates belong to the owning Stack workspace and UCNS; their successful execution does not validate EDCM readouts. The full-stack fixture proves identity separation, deterministic measurement, `NA != 0`, fail-closed producer validation, canon/manifest epoch rotation, and no proof-status transfer. @@ -300,7 +284,7 @@ Optional skips are explicit. Fake sibling implementations may test adversarial c - Historical measurement modules retain provenance until the explicit metadata-reconciliation pass. - Code and documentation include runnable usage guidance, integration notes, limitations, and `hmmm` boundaries. - EDCM vendors the bounded build/evidence subset from - `The-Interdependency/skill-lib@a1c6a7124af537ee9937b6fc6084940091982fe5`. + `The-Interdependency/skill-lib@dd5027d99516831c0dcb83a176a67140d3819b66`. The canonical drift checker and msdmd collector run in `.github/workflows/skill-compliance.yml`; repo-local copies are consumers, never authority. @@ -308,7 +292,7 @@ Optional skips are explicit. Fake sibling implementations may test adversarial c ## Usage guidance -For new text-gonol work, start in EDCM. Resolve the exact source/admission profile, consume current METAPAT affixiation semantics and current UCNS geometry, preserve `hmmm` where geometry is unresolved, complete and independently replay the declared construction, and only then design a separately frozen EDCM measurement. +For active construction use Stack and UCNS. For measurement, submit raw input to `build_default_layers().run()`. Never resubmit a result or fabricate derived output fields. See `docs/migrations/0.2.0-audit-repair.md` for the parser, result and codec transitions. For historical UCNS observation experiments, use the exact pinned producer and frozen vocabulary named by the historical artifact. Do not rewrite historical evidence and do not read its old producer boundary forward into current architecture. @@ -316,7 +300,7 @@ For historical UCNS observation experiments, use the exact pinned producer and f Still unresolved: -- exact EDCM character-admission units for profiles that have not selected one; +- exact Stack character-admission units for profiles that have not selected one; - source-supported complete English morphology law; - exact UCNS native Möbius-carrier affixiation/coupling geometry and direct distant-scale coupling; - EDCM projection, metric, benchmark, and falsifier for completed recursive text-gonol evaluation; @@ -324,4 +308,4 @@ Still unresolved: - mutation-level verification for the repository-wide CONTRACTS/CHECKS graph; - remaining historical L0/L1/L2/L3 split, P assignment, matrix wiring, bidirectional alerts, and Bridge-home decisions. -These unresolveds do not reopen measurement authority, METAPAT semantic ownership, UCNS geometric authority, EDCM text-domain construction ownership, canonical evidence schemas, certification policy, integrity guarantees, or the proof-transfer firewall. +These unresolveds do not reopen measurement authority, METAPAT semantic ownership, UCNS geometric authority, Stack language-construction ownership, canonical evidence schemas, certification policy, integrity guarantees, or the proof-transfer firewall. diff --git a/README.md b/README.md index 05c6e857..a4198fea 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,10 @@ # EDCM -EDCM is the Energy–Dissonance Circuit Model research, text-gonol construction, and measurement repository. +EDCM is the Energy–Dissonance Circuit Model measurement and evaluation repository. -The repository has four deliberately separate surfaces: +The active package is **0.2.0**, candidate `edcm-measurement-v2`. It preserves the frozen v1 canon data and metric equations while repairing transcript intake, result provenance and codec fidelity. Result schema **2.0.0** hashes every emitted compartment; codec **2** retains source text and token canon records. See the [migration and repair record](docs/migrations/0.2.0-audit-repair.md). -1. **Frozen maintained baseline:** `edcm/measurement/`, preserved as candidate `edcm-measurement-v1` with byte-checked canon and provenance. -2. **Text-domain gonol construction:** EDCM-owned character admission and linguistic/semantic construction using current METAPAT affixiation semantics and current UCNS geometry. -3. **Experiment-first joint program:** reproducible UCNS–EDCM experiments that determine which structural and measurement candidates deserve later canon review. -4. **Historical corpus-observation profiles:** pinned EDCM/UCNS producer epochs used to expose assumptions against full real-system corpora. They are observation/replay evidence, not the definition of current text construction. - -The baseline is executable. Text construction does not activate measurement. Neither is automatically the final UCNS–EDCM canon. +The repository separates current measurement, candidate experiments, and exact historical corpus/construction replay. Active language construction belongs to Stack and consumes UCNS constructors. No package, representation or passing test establishes empirical validity or selects canon. ## UCNS–EDCM canon @@ -44,35 +39,20 @@ may carry a source-pinned copy but is not the mathematical authority. ## Gonol language boundary -The active authority split is: - -```text -METAPAT -> affixiation semantics and relational-integration invariants -UCNS -> gonol geometry, native Möbius/Public Gonol carrier, - geometrically established operations -EDCM -> text-domain admission and linguistic/semantic gonol construction -EDCM -> separately frozen measurement projections and falsifiers -``` - -For active EDCM text construction: - -```text -every admitted character is a gonol -``` - -EDCM owns the source/profile that determines what is admitted as a character. If a profile has not selected Unicode code point, grapheme, exact Public Gonol glyph inventory, or another explicit unit, that admission boundary remains `hmmm`; UCNS does not silently choose it merely because UCNS owns the geometry. +The current authority split is: -Current EDCM text construction uses declared scale option sets rather than a mandatory adjacent-scale ladder. `edcm.gonol` is the implemented candidate constructor for closing one gonol at an admissible scale. None of its scale options is selected canon, and construction does not activate measurement. Suffix-coupling exceptions are carried by the closed suffix gonol, such as `ing` carrying `suffix-coupling.final-y-after-consonant = preserve-y`, rather than by a global morphology law. UCNS coupling geometry remains `hmmm` unless an explicit matching geometry authority is supplied. +| Owner | Responsibility | +|---|---| +| METAPAT | Affixiation semantics and relational-integration invariants | +| UCNS | Gonol objects, constructors, and geometry | +| Stack | Active language-gonol construction research and source/admission profiles | +| EDCM | Measurement/evaluation only | -Affixiation is defined by METAPAT. UCNS owns any exact geometric realization. EDCM applies affixiation to text-domain gonols. Once closed, a gonol is atomic at any scale. Closed gonols may participate directly at any admissible scale without reopening, while constituent identity and provenance remain recoverable. +For new language construction, start in [Stack English](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/english-gonol) or [Stack Python](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/python-gonol), consuming UCNS constructors and geometry. These source links pin the authority comparison used for this repair; resolve current owning commits before new research. -Do not insert conventional NLP token IDs, subword pieces, opaque external embedding vectors, or whole-string hashes as substitutes for gonol identity. Source prose, dictionaries, corpora, labels, and annotations may remain evidence and provenance; they become gonol semantics only through explicit EDCM construction. +Historical `edcm.gonol`, `edcm.language`, lexical-floor and sealed profile artifacts remain explicit replay surfaces. They confer no active construction authority on EDCM. There is no universal mandatory adjacent-scale ladder. Construction reproducibility does not validate EDCM measurement; an unresolved UCNS operation remains `hmmm`. -Public Gonol operations are usable only where current UCNS geometry establishes them. Unicode names, dictionary definitions, glyph shape, adjacency, and conventional punctuation grammar do not define a UCNS operation. Unresolved geometry remains `hmmm` rather than being filled with an invented carrier, scale rule, or semantic inference. - -A reproducible gonol construction establishes only that construction. Any EDCM measurement projection is frozen and evaluated separately. - -See [`docs/GONOL_LANGUAGE_BOUNDARY.md`](docs/GONOL_LANGUAGE_BOUNDARY.md). +See [the language boundary](docs/GONOL_LANGUAGE_BOUNDARY.md) and [the 0.2 migration](docs/migrations/0.2.0-audit-repair.md). ## First joint experiment @@ -195,7 +175,7 @@ retroactively turn the profile observation into formal geometry or empirical validation. `canon_selection` remains null, and EDCM/METAPAT activation remains inactive. -## Frozen maintained baseline +## Maintained measurement candidate `edcm/measurement/` consolidates the reviewed structural-measurement lineage from: @@ -211,7 +191,7 @@ It contains: - projection and risk surfaces; - provenance and integrity gates. -Its maintained identity is useful as a baseline candidate. Integrity means the implementation did not drift; it does not mean the readouts are empirically validated. +The v1 implementation remains frozen at its historical commits; 0.2 uses candidate v2. Its maintained identity is useful as a baseline candidate. Integrity means the implementation did not drift; it does not mean the readouts are empirically validated. ## Install and validate the baseline @@ -314,9 +294,9 @@ A legitimate baseline-canon change requires a new versioned file and migration r The active shared-stack boundary separates: -- source evidence and EDCM text-admission profile; +- exact source evidence and the declared measurement input profile; - METAPAT semantic/affixiation authority; -- EDCM text-gonol construction identity and receipts; +- externally constructed gonol identities and receipts where a declared evaluator consumes them; - UCNS carrier/geometry identity and unresolved geometry; - exact pinned historical UCNS word-gonol observations where replay profiles are used; - typed UCNS geometry and factorization absence in historical adapters; @@ -338,7 +318,7 @@ Unavailable evidence is typed absence. A candidate may fail scope, return an exp No UCNS or METAPAT status validates EDCM readouts, external truth, diagnosis, intention, morality, or consciousness. -A completed EDCM text-gonol construction likewise does not establish measurement validity. +A completed gonol construction likewise does not establish measurement validity. ## Repository provenance @@ -346,10 +326,12 @@ Historical implementation, source packets, repair handoffs, and prior adapter co ## Usage guidance -For new text-gonol work, start in EDCM and follow [`docs/GONOL_LANGUAGE_BOUNDARY.md`](docs/GONOL_LANGUAGE_BOUNDARY.md): resolve the source/admission profile, import METAPAT affixiation semantics, supply explicit UCNS geometry authority when geometry is claimed, build and replay the declared construction, and freeze any later measurement separately. +Use `edcm.build_default_layers().run({"transcript": text})` with raw input fields. Output-only fields are rejected; submit the original input rather than a previous result. The parser retains continuation lines and mixed recognized label formats; `parsed.source_text` retains exact input bytes after UTF-8 encoding. A line matching a speaker-label grammar starts a new turn; disambiguate label-like prose before measurement. + +For active construction use the Stack workspaces above. For historical replay use both the exact EDCM and UCNS producer commits named by the artifact. New executions with 0.2 are new evidence, not byte-identical historical reruns. -For historical experiment replay, use the exact historical producer commit and profile named by the artifact; do not repin or reinterpret sealed evidence as current authority. +See [upgrade avenues](docs/UPGRADE_AVENUES.md) for the next candidate and usability decisions. ## hmmm -The exact EDCM character-admission unit remains profile-specific where not selected. The source-supported complete English morphology law, exact UCNS native Möbius-carrier affixiation/coupling geometry, and direct distant-scale coupling remain unresolved. EDCM has not selected a lawful projection, information-loss account, metric, benchmark, or falsifier for evaluating completed recursive text-gonol constructions. Historical MultiWOZ seals remain represented evidence, not measurement validity; external replication and broader carrier coverage remain separate unresolveds. +Language admission is owned by its Stack workspace. The source-supported complete English morphology law, exact UCNS native Möbius-carrier affixiation/coupling geometry, and direct distant-scale coupling remain unresolved. EDCM has not selected a lawful projection, information-loss account, metric, benchmark, or falsifier for evaluating completed recursive text-gonol constructions. Historical MultiWOZ seals remain represented evidence, not measurement validity; external replication and broader carrier coverage remain separate unresolveds. diff --git a/docs/EDCM_MATHEMATICS.md b/docs/EDCM_MATHEMATICS.md index 78d4ab3a..fd41af5c 100644 --- a/docs/EDCM_MATHEMATICS.md +++ b/docs/EDCM_MATHEMATICS.md @@ -1,8 +1,8 @@ # EDCM mathematical reference -Version: 0.1.0 +Version: 0.2.0 -Date: 2026-08-02 +Date: 2026-09-17 Status: complete compiled reference for the mathematics currently declared or implemented in this repository; not a joint UCNS–EDCM canon selection @@ -13,7 +13,7 @@ This document is the human-readable copy of the current Energy–Dissonance Circuit Model mathematics. Its scope is exact: - `edcm/measurement/` is the maintained implementation authority for the - frozen baseline candidate `edcm-measurement-v1`; + current baseline candidate `edcm-measurement-v2`; - `edcm/ucns_objects.py` is the implemented EDCM signed-axis construction layer, not formal UCNS geometry; - `edcm/edcmucns/` is the implemented v0.3.1 EDCM architecture layer; its @@ -67,7 +67,10 @@ u_i=(a_i,x_i), $$ where $a_i$ is the speaker identifier and $x_i$ is the exact turn text. -Turn order and multiplicity are load-bearing. +Turn order and multiplicity are load-bearing. The 0.2.0 parser recognizes each +line independently, retaining continuation lines and preamble. Exact raw labels, +spacing and line endings are retained separately in `source_text`; turn text +excludes recognized label syntax. See the [migration](migrations/0.2.0-audit-repair.md). The maintained parser supports two round partitions: @@ -1300,13 +1303,14 @@ $d(x)$ and then attached to the report. The immutable evidence file also has a SHA-256 over its exact serialized bytes. These identities detect drift; they do not prove truth, authorship, or empirical validity. -For `edcm.shared-stack-result/1.2.0`, `epoch_identity` is $d(x)$ over the -METAPAT canon/provenance digests, UCNS profile identity/scope/source/options, -EDCM manifest hash, and selected semantic-authority, UCNS-profile, and -measurement implementations. `result_identity` is $d(x)$ over that epoch -identity plus source evidence, the complete UCNS profile observation, EDCM -readouts, factorization evidence, and status evidence. Geometry absence remains -a typed compartment and does not become a fabricated geometry identity. +For `edcm.shared-stack-result/2.0.0`, `epoch_identity` is $d(x)$ over the +result-schema version, METAPAT canon/provenance digests, UCNS profile +identity/scope/source/options, EDCM manifest hash, and selected semantic-authority, +UCNS-profile, and measurement implementations. `result_identity` is $d(x)$ over +the complete emitted contract with only `result_identity` removed. This includes +all typed absence compartments, all implementation provenance and unresolved +constraints. JSON serialization rejects non-finite numbers. Geometry and +factorization remain typed `NA`; unsupported evidence is rejected. ## 16. What is not yet mathematics diff --git a/docs/GONOL_LANGUAGE_BOUNDARY.md b/docs/GONOL_LANGUAGE_BOUNDARY.md index c9497436..d4f24c51 100644 --- a/docs/GONOL_LANGUAGE_BOUNDARY.md +++ b/docs/GONOL_LANGUAGE_BOUNDARY.md @@ -1,177 +1,54 @@ -# EDCM gonol language boundary +# Gonol language construction and EDCM evaluation -**Status:** active EDCM text-construction and measurement boundary. -**Authority split:** METAPAT owns affixiation semantics; UCNS owns gonol/Möbius/Public Gonol geometry; EDCM owns text-domain admission and linguistic/semantic gonol construction and measurement. -**Corrected:** 2026-08-21 after UCNS geometry-only canon and skill-lib `gonol-build` authority repair. +Status: current routing correction, 2026-09-17. This replaces EDCM's former +active text-construction ownership. Historical source identities remain unchanged. -## Governing authorities +| Owner | Responsibility | +|---|---| +| METAPAT | Its semantic contracts and affixiation meaning | +| UCNS | Gonol objects, constructors, and geometry | +| Stack | Active language-gonol construction research and source/admission profiles | +| EDCM | Measurement/evaluation only | -The current stack separates meaning, geometry, text construction, and measurement: - -```text -METAPAT - affixiation semantics and relational integration invariants - ↓ -UCNS - gonol geometry, native Möbius/Public Gonol carrier, - geometrically established operations - ↓ -EDCM - text-domain admission and linguistic/semantic gonol construction - ↓ -EDCM measurement - separately declared observations, projections, metrics, and falsifiers -``` - -Authority does not transfer automatically between these layers. - -- METAPAT semantic authority does not prove UCNS geometry. -- UCNS geometry does not choose EDCM text sources, morphology, definitions, or semantic relations. -- EDCM construction does not validate EDCM measurement. -- EDCM measurement does not validate METAPAT or UCNS. - -## Character rule - -For active EDCM text construction: - -```text -every admitted character is a gonol -``` - -This is an EDCM text-domain rule. - -EDCM owns the declared source/profile that determines what is admitted as a character. A profile may select Unicode code points, graphemes, the exact Public Gonol glyph inventory, or another explicitly defined character unit. If that admission unit is not yet selected for a construction, it remains `hmmm`; UCNS does not silently decide it merely because UCNS supplies the geometry. - -Every admitted occurrence remains separately addressable. Repeated characters may share gonol identity where the governing construction says they are the same gonol, while occurrence order, multiplicity, source location, and provenance remain preserved. - -## Active text construction - -Current EDCM text construction uses declared scale option sets rather than a mandatory adjacent-scale ladder. Every admitted character is a gonol, but EDCM must not encode `character -> word -> definition -> recursive` as the only lawful construction path. - -Once closed, a gonol is atomic at any scale. Closed gonols may participate directly at any admissible scale without reopening, while identity, order, multiplicity, source positions, relation identity, and provenance remain recoverable. - -`edcm.gonol` is the implemented candidate constructor for closing one gonol through a declared scale option set. Its current option sets include character, word, suffix, suffix-coupling, definition, and recursive relation scales. None is selected canon. UCNS coupling geometry remains `hmmm`, and absent `ucns.public_gonol` does not prevent candidate construction. - -When a non-character construction uses a direct source string, each admitted source unit is also closed as a source-character gonol. Those character gonols remain recoverable evidence; they do not force a mandatory adjacent-scale construction ladder. - -Relationships that constitute a gonol enter the construction. They are not merely external semantic edges. Sidecars may index, cache, project, or record provenance; they do not replace intrinsic relational content. - -## Affixiation - -Affixiation is not defined by EDCM and is not defined by UCNS. - -METAPAT defines affixiation as a declared relation among already-bounded participants that preserves their individual addressability, identities, and provenance while the relation may integrate as a higher-scale object-whole. An affixiated whole may participate recursively without erasing its constituents. - -UCNS owns any exact geometric realization of that operation. The native Möbius/Public Gonol carrier is the current geometric authority. Where the precise coupling operation has not yet been constructed, it remains `hmmm`; EDCM must not fill the gap with an invented carrier, topology, scale increment, arity rule, containment rule, or coupling law. - -EDCM applies affixiation to text-domain gonols. Linguistic prefixes and suffixes are one instance of affixiation; they do not define affixiation. - -Suffix-coupling options that affect a suffix relation are carried by the relevant closed suffix gonol. For example, a closed `ing` suffix gonol may carry `suffix-coupling.final-y-after-consonant = preserve-y`; the suffix-coupling construction preserves that option through the suffix participant instead of storing an `ing` exception in a global morphology law or reopening the suffix. - -The complete English root, stem, affix, irregular-transformation, and family law remains unresolved unless source-backed EDCM evidence establishes it. EDCM must not invent decomposition to complete a pipeline. - -## Public Gonol function positions - -UCNS owns the geometry of the exact 157-position Public Gonol carrier and any function operation that geometry actually establishes. - -EDCM may use a Public Gonol position in text construction, but it may not derive the position's operation from Unicode names, dictionary definitions, conventional punctuation grammar, glyph shape, or adjacency. An unresolved operation remains `hmmm`. - -When an operation is geometrically authorized, an EDCM construction must preserve the exact function identity, occurrence address, ordered participants, source/profile identity, carrier/construction identity, result identity, and provenance needed for replay. - -## No hidden token or vector layer - -EDCM must not insert conventional NLP token IDs, subword IDs, opaque embedding vectors, or whole-string hashes as substitutes for gonol identity. - -Source prose, dictionary material, corpora, labels, and annotations may remain evidence and provenance. Their inclusion does not by itself make them gonol semantics. A text-domain relationship becomes authoritative only through an EDCM construction whose source, admission, relation, closure, and replay boundaries are explicit. - -## Historical evidence - -EDCM contains sealed historical UCNS/OEWN, lexical-floor, word-gonol, token-named, morphology, and other experiments. Preserve them exactly for reproducibility. - -Historical names and producer boundaries remain historical evidence. They do not restore the former rule that UCNS owns lexical construction and they do not override current UCNS geometry-only canon or this EDCM text-domain boundary. - -When reproducing a sealed experiment, use its exact historical commits and artifacts. When beginning new text construction, use the current authority split above. - -## EDCM measurement boundary - -Construction and measurement remain separate. - -EDCM may declare a measurement projection over constructed gonols only when the projection, information loss, metric, aggregation, baseline, partitioning, stopping rules, and falsifiers are explicitly frozen as required by the governing experiment. - -A reproducible text-gonol construction establishes only that construction. It does not establish semantic quality, compression advantage, reconstruction quality, embedding equivalence, cognition, consciousness, or measurement validity. - -## Evidence and replay requirements - -A completed text-gonol construction must bind the material identities that determine it, including as applicable: - -1. current METAPAT affixiation authority; -2. current UCNS geometric authority; -3. exact EDCM construction code/profile; -4. exact source artifacts and admission rules; -5. participant identity, occurrence, order, multiplicity, relation identity, scale, and provenance; -6. closure and atomic-participation boundaries; -7. unresolved state and information loss; -8. a deterministic construction receipt; and -9. independent complete reconstruction or replay when completion is claimed. - -Preflight real resource requirements before a complete run. Once a healthy admitted run begins, let it reach its natural terminal condition unless a genuine external resource/safety boundary or preregistered load-bearing stopping rule fires. +This boundary consumes [skill-lib gonol-build at dd5027d](https://github.com/The-Interdependency/skill-lib/blob/dd5027d99516831c0dcb83a176a67140d3819b66/gonol-build/SKILL.md) +and [Stack at 250a0af](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a). +Those sources establish current placement, not empirical validity. ## Usage guidance -Copy-pasteable unified candidate: +For new construction start in the owning workspace: + +- [Stack English](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/english-gonol). +- [Stack Python](https://github.com/The-Interdependency/stack/tree/250a0afb7077b036a6c537411d004fa095c8b24a/research/python-gonol). -```python -from edcm.gonol import construct_gonol, replay_gonol +Resolve the current workspace's admission, participant eligibility, constitutive +relations and closure rules. Consume UCNS constructors and geometry. Preserve +identity, order, multiplicity, occurrence positions and provenance. Once closed, +a gonol participates atomically at an admissible consuming scale; no universal +mandatory adjacent-scale ladder is imposed. Pronunciation participates only if +the owning construction explicitly admits it. -word = construct_gonol(scale="word", source="try", source_id="example:try") -ing = construct_gonol( - scale="suffix", - source="ing", - source_id="example:ing", - carried_options=(("suffix-coupling.final-y-after-consonant", "preserve-y"),), -) -definition = construct_gonol( - scale="definition", - relation="example:definition-evidence", - source="to divide with a sharp edge", - participants=(word.gonol,), - source_id="example:cut#1", -) -recursive = construct_gonol( - scale="recursive", - relation="example:mentions", - participants=(word.gonol, definition.gonol), - source_id="example:relation#1", -) -suffix_coupling = construct_gonol( - scale="suffix-coupling", - participants=(word.gonol, ing.gonol), - source_id="example:trying#1", -) -assert recursive.receipt_digest == replay_gonol(receipt=recursive).receipt_digest -assert suffix_coupling.receipt_digest == replay_gonol(receipt=suffix_coupling).receipt_digest -``` +An unresolved operation remains `hmmm`. Unicode names, dictionary definitions, +glyph shape and conventional grammar cannot supply a missing UCNS geometry law. -If an explicit `geometry_authority` supplies `PUBLIC_GONOL_157` with a digest matching the pinned Public Gonol identity, `edcm.gonol` observes source-unit positions. If no authority is supplied, construction records geometry as `hmmm` and still closes the candidate. It does not probe ambient imports and does not mutate `sys.path`. +EDCM may evaluate the resulting construction only through a separately declared +projection, information-loss account, metric, baseline, partitions, aggregation, +stopping rules and falsifier. Construction reproducibility does not validate +EDCM measurement. No geometry or semantic proof status transfers. -For new text-gonol work: +## Historical compatibility -1. start in EDCM; -2. resolve the exact EDCM source/admission profile; -3. import current METAPAT affixiation invariants rather than redefining them; -4. consume current UCNS geometry rather than moving text semantics into UCNS; -5. close gonols through declared scale option sets under explicit EDCM receipts; use `edcm.gonol`; -6. keep unresolved UCNS geometric operations as `hmmm`; -7. replay the complete declared construction before claiming completion; and -8. freeze any later EDCM measurement separately. +`edcm.gonol`, `edcm.language`, lexical-floor artifacts and historical word-gonol +profiles retain their historical identities for explicit replay. They are not +entrypoints for new construction research. Reproduce sealed claims with the +exact original EDCM, UCNS and source commits, not the current package under old +candidate labels. Retaining provenance does not restore superseded ownership. -For UCNS geometry work, work in UCNS. For changes to the meaning of affixiation, work in METAPAT. +EDCM's conventional transcript parser is a measurement projection, not a gonol +constructor. Its source-retention repair does not claim geometric identity. ## hmmm -- the exact EDCM character-admission unit for any source/profile that has not yet selected one; -- the source-supported complete English morphology law; -- the exact UCNS Möbius-carrier affixiation/coupling law exposed by implementation; -- which scale option sets and recursive relations, if any, are later selected, and the exact UCNS geometry for those relations; -- executable direct coupling across distant recursive scales; -- the EDCM projection, information-loss accounting, metric, benchmark, and falsifier for recursive text-gonol evaluation. +Exact missing UCNS operations, future graduation of language workspaces, +independent construction evaluation, and EDCM measurement validity remain +source-specific unresolveds. Route repairs to the owning layer. diff --git a/docs/UPGRADE_AVENUES.md b/docs/UPGRADE_AVENUES.md new file mode 100644 index 00000000..8333643c --- /dev/null +++ b/docs/UPGRADE_AVENUES.md @@ -0,0 +1,60 @@ +# EDCM upgrade avenues + +Decision basis: the 2026-09-17 audit and the versioned 0.2.0 repair. These are +proposed work packets, not delivered capabilities or validated claims. + +Start with explainable source attribution. Then test one narrowly defined +measurement candidate against independent labels before expanding integration. + +| Priority | Avenue | Concrete next deliverable | Advancement gate | +|---|---|---|---| +| 1 | Evidence spans and parser accounting | For each readout expose contributing source spans, rule IDs, denominator, round membership and retained-but-unmatched text. Bind offsets to exact source identity. | Every attributed span slices the original source correctly across Unicode, CRLF, mixed labels and continuations; coverage gaps stay visible. No silent source loss. | +| 2 | Independent validity study | Freeze one operational target, annotation/adjudication protocol, trivial and task-specific baselines, dialogue-level partitions, metric, uncertainty interval and falsifier before inspecting new outcomes. | Beat preregistered baselines on independently held-out evidence with the declared effect margin; report subgroup failures and uncertainty. Do not tune on the sealed booking test set. | +| 3 | Scope and order candidate | Build a separate versioned readout that tests negation, quotation, speaker attribution, repetition and order against minimal pairs. Declare what source information the projection loses. | Correct directional separation on frozen, unseen counterexamples; failure of a pair blocks the associated scope claim. Preserve v1/v2 evidence under their original IDs. | +| 4 | Recovery dynamics stress test | Extend normalized recovered-dissonance experiments with stalled, oscillating, regressing, adversarial and differently sized trajectories. Freeze sampling and aggregation first. | Separate improvement from length, repetition and reset artifacts; survive unseen trajectories with specified falsifiers. Four controlled successes do not establish real-dialogue validity. | +| 5 | Exact construction receipt consumer | In EDCM, consume one existing pinned Stack construction receipt using UCNS objects/constructors/geometry and a declared evaluation projection. Keep producer absence typed. | Reconcile source, object identity, order, multiplicity, closure and hashes against the producer. No reconstructed geometry or proof-to-measurement transfer. Construction belongs upstream. | + +Priority 1 is bounded engineering. Priorities 2–4 require research design and new +evidence; their cost depends on label authority and custody. Priority 5 depends +on a concrete producer contract, not merely repository availability. It should +follow a useful evaluation question rather than precede one. + +## Evidence limiting promotion + +The sealed [booking-outcome findings](experiments/2026-08-02-multiwoz-booking-outcome-holdout-findings.md) +report 661 test events, balanced accuracy 0.521165 with 95% interval +[0.465606, 0.573938], and sensitivity 0.4698, below the declared 0.50 floor. +That bounded candidate's sensitivity hypothesis is falsified. This is neither +validation of the maintained axes nor a universal disproof of every EDCM model. +The repair creates a new measurement candidate, not a new validity result. + +The audited multiline refusal is now retained, but “I cannot do this.” still +has no hit on the frozen refusal axis. The historical scope experiment also +exposes zero constraint signals on its tested distinctions. These motivate +explicit span explanations and a new scope candidate, not an undocumented +change to frozen markers. + +Normalized recovered dissonance survived four controlled trajectories in its +recorded scope. Replicate the sealed evidence from its own pinned source before +extending it; controlled success alone cannot establish generalization. + +## External methodological support + +Using a predictor that ignores input features gives a transparent trivial +baseline; this is the explicit purpose of scikit-learn's +[DummyClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.dummy.DummyClassifier.html). +If a future readout claims probability, fit and assess its calibration on data +separate from estimator training, following the independence boundary described +in the [calibration documentation](https://scikit-learn.org/stable/modules/calibration.html). +These recommendations do not require adding scikit-learn to EDCM's runtime. + +Define the target construct and its operationalization before interpreting a +score as the construct itself. [Jacobs and Wallach, Measurement and Fairness](https://arxiv.org/abs/1912.05511) +provides measurement-model context for that distinction. Applying it here is a +research recommendation, not evidence that an EDCM axis is valid. + +## hmmm + +Which single outcome matters most to the intended consumer; who owns independent +labels and sealed-test custody; the minimum worthwhile effect; the relevant +language/domain coverage; and the exact next receipt producer remain open. diff --git a/docs/integrity-gates.md b/docs/integrity-gates.md index 4993f261..671d48fd 100644 --- a/docs/integrity-gates.md +++ b/docs/integrity-gates.md @@ -76,7 +76,7 @@ This prevents a false green where source tests pass while packaged resources or ## Skill-lib and msdmd EDCM vendors a bounded build/evidence subset from -`The-Interdependency/skill-lib@a1c6a7124af537ee9937b6fc6084940091982fe5`. +`The-Interdependency/skill-lib@dd5027d99516831c0dcb83a176a67140d3819b66`. The skill-compliance workflow checks those files byte-for-byte, generates the canonical `edcm_msdmd.ts` collection, compares it with the tracked collection, and runs the EDCM-native metadata validator. @@ -86,7 +86,7 @@ Local validation: ```bash python /path/to/skill-lib/tools/check_consumer_drift.py . \ --canon-root /path/to/skill-lib \ - --sha a1c6a7124af537ee9937b6fc6084940091982fe5 \ + --sha dd5027d99516831c0dcb83a176a67140d3819b66 \ --strict-sha --require-vendored PYTHONPATH=/path/to/skill-lib python /path/to/skill-lib/msdmd/collect.py \ diff --git a/docs/migrations/0.2.0-audit-repair.md b/docs/migrations/0.2.0-audit-repair.md new file mode 100644 index 00000000..bced98ff --- /dev/null +++ b/docs/migrations/0.2.0-audit-repair.md @@ -0,0 +1,83 @@ +# EDCM 0.2.0 audit repair + +Date: 2026-09-17. Starting state: `ddc89a97ebbcf0a5863dad6e633b01b520e9bccf`. + +This is a behavior-changing repair. It does not establish empirical validity, +select canon, or change the four frozen measurement JSON resources. + +| Contract | Previous | Current | +|---|---|---| +| Package and measurement implementation | 0.1.0 | 0.2.0 | +| Maintained measurement candidate | edcm-measurement-v1 | edcm-measurement-v2 | +| Shared result schema | 1.2.0 | 2.0.0 | +| Transcript compression format | 1 | 2 | +| Booking runner candidate | edcm.maintained-terminal-progress/0.1.0 | edcm.maintained-terminal-progress/0.2.0 | + +## Repair and owning files + +| Defect | Repair | Owning surface | +|---|---|---| +| Multiline and mixed-label text disappeared before measurement | Parse every line; retain continuation, preamble, empty turns and exact source text | `measurement/parser/turns_rounds.py` | +| Supplied round dictionaries became canonical measured output | Reject output-only fields at public intake; clear stale measurement state; validate completed readouts | `layers.py`, `shared_stack.py` | +| Unsupported geometry and retired inputs crossed optional-package boundaries | Reject them at public intake regardless of installed packages; keep geometry/factorization typed `NA` | `layers.py`, `ucns_adapter.py`, `shared_stack.py` | +| Result identity omitted emitted compartments | Hash the complete result except its self-digest, using finite JSON; bind schema version into epoch | `shared_stack.py` | +| Active construction ownership disagreed with current upstream instructions | Route construction to Stack/UCNS; preserve EDCM as measurement/evaluation owner | root instructions, boundary document, generated indexes, authority tests | +| “Lossless” codec dropped bone entries | Preserve every bone field and exact source; reject partial metrics and unsupported codec versions | `measurement/compress.py` | + +Regression witnesses are in `tests/test_audit_regressions.py`. Authority tests +cover current routing. Base, exact optional-producer, historical experiment, +integrity, metadata, skill-drift and clean-wheel gates remain distinct. + +## Consumer migration + +Pass only raw inputs to `build_default_layers().run()`. Resubmitting a completed +pipeline dictionary now raises `ValueError`. Remove derived `rounds`, projections, +alerts, integration status, geometry, provenance and result fields; supply the +original transcript and authorized source inputs instead. Optional package +absence never authorizes retired evidence. + +`build_result_contract()` assembles trusted in-process completed layer state. +It is not a raw-input ingress or an authentication API. A boolean execution flag +alone is not sufficient: complete, finite, indexed measurements and source must +also be present. Public `.run()` rejects that flag in caller input. + +The parser recognizes labels at line starts, per line, across supported formats. +Unlabelled lines continue the current turn; preamble belongs to `SPEAKER`. +Label-like prose is syntactically ambiguous: use a declared input convention. +`ParsedTranscript.source_text` retains exact labels, spacing and line endings; +turn text excludes label syntax. A manually constructed parsed object may use +`source_text=None` to express unavailable original source. + +Recompute result identities under schema 2.0.0. Do not compare old and new hashes +as if they described an unchanged serialization. The whole-result hash detects +content changes, not authorship, truth, or empirical validity. + +Codec 2 requires its explicit version and complete token entries. Old codec 1 +archives cannot recover entries already discarded. Decode those archives with +the original pinned producer and label the missing information; do not silently +upgrade them to a lossless claim. Re-encode original source with 0.2.0 when it is +available. No duplicate legacy decoder is installed on the active path. + +## Historical replay and research + +Sealed reports, original candidate IDs, exact source commits, holdout outcomes +and frozen marker resources retain their original bytes. Replay a historical +claim from the EDCM and UCNS commits recorded in its artifact. Running a current +experiment runner creates new candidate evidence; it does not reproduce the old +measurement implementation merely because the experiment family name matches. + +The parser repair can change metrics even for single labelled turns and can +change round membership for mixed formats or preamble. Existing fitted holdout +coefficients are historical evidence, not validation of candidate v2. This +repair does not retune thresholds, reinterpret negative results, or rerun a +sealed test to promote the new implementation. + +The phrase “I cannot do this.” now reaches measurement in the audited multiline +example but still scores zero on the frozen refusal marker axis. Source fidelity +and construct validity are separate. See [upgrade avenues](../UPGRADE_AVENUES.md). + +## hmmm + +Independent validity of the maintained axes, source span attribution, a future +validated construction-receipt consumer, and cryptographic producer +authentication remain unresolved. None is implied by a passing repair gate. diff --git a/docs/shared-stack-result.md b/docs/shared-stack-result.md index b0f40b04..1426f76b 100644 --- a/docs/shared-stack-result.md +++ b/docs/shared-stack-result.md @@ -5,11 +5,12 @@ the identities or authority of its contributors. ```text schema_id: edcm.shared-stack-result -schema_version: 1.2.0 +schema_version: 2.0.0 ``` -Version 1.2 adds the exact EDCM UCNS profile-observation compartment and keeps -geometry and factorization independently typed. +Version 2 rejects caller-supplied output fields and unsupported evidence, validates +completed measurement state, and binds every emitted compartment into result identity. +See [migration guidance](migrations/0.2.0-audit-repair.md). ## Compartments @@ -35,6 +36,8 @@ geometry and factorization independently typed. `epoch_identity` binds: +- the result-schema version; + - METAPAT canon and provenance; - UCNS profile id, version, scope, exact options, and pinned source commit; - the Unicode-scalar source domain and exact ordered 25-value SPACE pin, @@ -42,10 +45,18 @@ geometry and factorization independently typed. - EDCM policy-manifest identity; - selected semantic-authority, UCNS-profile, and measurement implementations. -`result_identity` additionally binds source evidence, exact profile -observations, EDCM readouts, independently attached evidence, and status flags. +`result_identity` is SHA-256 of the entire emitted contract except +`result_identity`, serialized as UTF-8 sorted-key compact JSON with +`ensure_ascii=False` and `allow_nan=False`. This includes both typed absence +compartments, all implementation provenance and unresolved constraints. Changing corpus evidence changes result identity without pretending that the -profile configuration changed. +profile configuration changed. These digests are content identities, not signatures. + +The public ingress is `build_default_layers().run(raw_inputs)`. Supplied rounds, +projections, statuses, execution flags and results are rejected. +`build_result_contract()` is an assembly helper for trusted in-process completed +layer state; it validates measurement shape, finite ranges, ordered indices and +source presence, but cannot authenticate a caller controlling Python execution. ## Full-stack usage @@ -78,7 +89,7 @@ The current path fails closed for profile identity or option drift, checkout package bytes that differ from the pinned tree, installed-package inventory or hash drift, executable-bytecode drift, malformed producer metadata, public alphabet drift, malformed turn containers, retired bridge/object/factorization -inputs, malformed METAPAT evidence, and transitive import failures. Only direct +inputs even without optional packages, caller-supplied output fields, malformed METAPAT evidence, and transitive import failures. Only direct optional-package absence becomes typed unavailability. ## hmmm diff --git a/edcm/__init__.py b/edcm/__init__.py index 90763d67..2f0137aa 100644 --- a/edcm/__init__.py +++ b/edcm/__init__.py @@ -28,7 +28,7 @@ # unresolved: UCNS observation digests and historical fork topology bindings provide content identity but not cryptographic producer authentication; formal Mobius coordinates and higher-gonol composition remain open # === END MODULE_BUILD === -__version__ = "0.1.0" +__version__ = "0.2.0" from . import edcmucns from . import measurement diff --git a/edcm/corpora/multiwoz21_booking_holdout.py b/edcm/corpora/multiwoz21_booking_holdout.py index 3353d237..139e49d5 100644 --- a/edcm/corpora/multiwoz21_booking_holdout.py +++ b/edcm/corpora/multiwoz21_booking_holdout.py @@ -145,7 +145,7 @@ SCHEMA_VERSION = "0.1.1" RECEIPT_SCHEMA_ID = "edcm.multiwoz21-booking-outcome-holdout-receipt" RECEIPT_SCHEMA_VERSION = "0.1.1" -CANDIDATE_ID = "edcm.maintained-terminal-progress/0.1.0" +CANDIDATE_ID = "edcm.maintained-terminal-progress/0.2.0" POSITIVE_LABEL = "Booking-Book" NEGATIVE_LABEL = "Booking-NoBook" PINNED_UCNS_COMMIT = "a98c9e6c69804a8a08d0786b1d8b450bb2c49a97" diff --git a/edcm/gonol.py b/edcm/gonol.py index c950472b..ab7caef7 100644 --- a/edcm/gonol.py +++ b/edcm/gonol.py @@ -1,3 +1,5 @@ +# Historical replay surface; active construction belongs to Stack and UCNS. +# See docs/GONOL_LANGUAGE_BOUNDARY.md; no active construction authority here. """Unified EDCM gonol candidate constructor. Usage guidance diff --git a/edcm/integrity.py b/edcm/integrity.py index 9f3b7f2d..80ce65b6 100644 --- a/edcm/integrity.py +++ b/edcm/integrity.py @@ -53,7 +53,7 @@ EXPECTED_MEASUREMENT_AUTHORITY = { "canonical": True, "source_of_truth": "The-Interdependency/edcm:edcm/measurement", - "implementation_version": "0.1.0", + "implementation_version": "0.2.0", "compatibility_policy": "edcmbone-provenance-only-v1", "consolidation_source_repository": "https://github.com/The-Interdependency/edcmbone", "consolidation_source_path": "backend_old/src/edcmbone/", diff --git a/edcm/language/__init__.py b/edcm/language/__init__.py index 9b3fd0fd..81d57f88 100644 --- a/edcm/language/__init__.py +++ b/edcm/language/__init__.py @@ -1,3 +1,5 @@ +# Historical replay surface; active construction belongs to Stack and UCNS. +# See docs/GONOL_LANGUAGE_BOUNDARY.md; no active construction authority here. """EDCM English lexical evidence over a UCNS-owned relational carrier.""" # === MODULE_BUILD === diff --git a/edcm/layers.py b/edcm/layers.py index 33a86e6e..78f457bc 100644 --- a/edcm/layers.py +++ b/edcm/layers.py @@ -21,13 +21,13 @@ # summary: Provenance-bearing EDCM stack with independently selected METAPAT semantic authority, exact UCNS word-gonol observation profile or typed absence, canonical local measurement, shared-stack composition, and final result-contract delivery. # owner: Erin Spencer # public_surface: LayerProvenance, MeasurementLayer, SemanticsLayer, CompositionLayer, DeliveryLayer, DefaultMeasurementLayer, DefaultCompositionLayer, DefaultDeliveryLayer, MissingMetapatSemanticAuthorityLayer, MetapatSemanticAuthorityLayer, MissingUCNSProfileLayer, UCNSProfileLayer, CompositeSemanticsLayer, ConsolidatedMeasurementLayer, SharedStackCompositionLayer, SharedStackDeliveryLayer, EDCMLayers, build_default_layers -# internal_surface: _record_layer, _local_provenance +# internal_surface: _record_layer, _local_provenance, _reject_retired_inputs # auth_boundary: none # storage_boundary: none # network_boundary: none # user_data_boundary: threads caller payloads through deterministic package-local layers; transcript content is hashed in final result identity # admin_only: false -# tests: tests.test_measurement, tests.test_ucns_adapter, tests.test_metapat_adapter, tests.test_shared_stack_contract +# tests: tests.test_measurement, tests.test_ucns_adapter, tests.test_metapat_adapter, tests.test_shared_stack_contract, tests.test_audit_regressions # rollout: default_enabled # rollback: restore prior layer assembly and remove shared-stack result delivery # requires: edcm_metapat_adapter, edcm_ucns_adapter, edcm_measurement, edcm_shared_stack @@ -52,12 +52,31 @@ from .shared_stack import build_result_contract from .ucns_adapter import ( ActualUCNSAdapter, + REJECTED_LEGACY_INPUTS, UCNSIntegrationStatus, missing_ucns_status, select_ucns_adapter, ) +# Raw input and completed layer state are different contracts. Reject stale +# output dictionaries instead of attributing their contents to this execution. +_MEASUREMENT_FIELDS = frozenset({ + "rounds", "agent_metrics", "alerts", "structural_density", "measurement_computed", +}) +_OUTPUT_FIELDS = _MEASUREMENT_FIELDS | frozenset({ + "measurement", "semantic_authority", "metapat_integration", "metapat_semantics", + "ucns_integration", "ucns_profile", "ucns_profile_observation", "ucns_geometry", + "semantics", "composition", "delivery", "layer_provenance", "edcm_result", +}) + + +def _reject_retired_inputs(payload: Mapping[str, Any]) -> None: + legacy = sorted(REJECTED_LEGACY_INPUTS.intersection(payload)) + if legacy: + raise ValueError("retired UCNS inputs are rejected: " + ", ".join(legacy)) + + @dataclass(frozen=True) class LayerProvenance: implementation_id: str @@ -162,6 +181,9 @@ class ConsolidatedMeasurementLayer: def measure(self, payload: dict[str, Any]) -> dict[str, Any]: transcript = payload.get("transcript") state = dict(payload) + for field in _MEASUREMENT_FIELDS: + state.pop(field, None) + state["measurement_computed"] = False state["measurement"] = "edcm.measurement" if not isinstance(transcript, str) or not transcript.strip(): @@ -180,6 +202,7 @@ def measure(self, payload: dict[str, Any]) -> dict[str, Any]: agent_metrics=[am.as_dict() for am in projections], alerts=[m.fire_alerts(am) for am in projections], structural_density=stats["structural_density"], + measurement_computed=True, ) return _record_layer(state, "measurement", self.provenance) @@ -254,6 +277,8 @@ def __init__(self, status: UCNSIntegrationStatus | None = None) -> None: def normalize(self, payload: dict[str, Any]) -> dict[str, Any]: state = dict(payload) + _reject_retired_inputs(state) + state.pop("ucns_geometry", None) state["ucns_profile"] = "unavailable" state["ucns_integration"] = self._status.as_dict() state.pop("ucns_profile_observation", None) @@ -372,6 +397,11 @@ class EDCMLayers: delivery: DeliveryLayer def run(self, payload: dict[str, Any]) -> dict[str, Any]: + """Execute raw inputs; derived output fields must never be resubmitted.""" + _reject_retired_inputs(payload) + supplied_outputs = sorted(_OUTPUT_FIELDS.intersection(payload)) + if supplied_outputs: + raise ValueError("output-only fields in pipeline input: " + ", ".join(supplied_outputs)) state = self.semantics.normalize(payload) state = self.measurement.measure(state) state = self.composition.compose(state) diff --git a/edcm/measurement/__init__.py b/edcm/measurement/__init__.py index 49659d57..54118f01 100644 --- a/edcm/measurement/__init__.py +++ b/edcm/measurement/__init__.py @@ -23,7 +23,7 @@ """ # Version of the maintained EDCM measurement surface. -__version__ = "0.1.0" +__version__ = "0.2.0" CONSOLIDATION_SOURCE_REPOSITORY = "https://github.com/The-Interdependency/edcmbone" CONSOLIDATION_SOURCE_PATH = "backend_old/src/edcmbone/" diff --git a/edcm/measurement/compress.py b/edcm/measurement/compress.py index e8c104f6..c88bfd85 100644 --- a/edcm/measurement/compress.py +++ b/edcm/measurement/compress.py @@ -1,12 +1,12 @@ """ edcmbone.compress ~~~~~~~~~~~~~~~~~ -Lossless codec for ParsedTranscript + RoundMetrics. +Version 2 lossless codec for parser-produced ParsedTranscript + RoundMetrics. -The encoding scheme is EDCM-aware: bones and flesh are stored in separate -streams, making the structural (constraint-skeleton) layer addressable without -full decompression. The final byte form uses zlib (DEFLATE) for entropy -coding; the EDCM structure does most of the modelling work. +The encoding keeps bone and flesh records interleaved in original token order, +including full bone entries and exact source text. The final byte form uses +zlib (DEFLATE); inspecting the JSON records requires decompression. Unsupported +versions are rejected rather than silently inventing discarded token metadata. Lossless guarantee ------------------ @@ -16,8 +16,8 @@ Compression-metric connection ------------------------------ The bone family sequence is treated as the "compressed structural text". -Its Shannon entropy is the theoretical minimum bits-per-bone under optimal -coding. compression_stats() returns this alongside byte-level ratios, +Its empirical Shannon entropy describes the observed family frequencies; it +is not a guarantee of achievable compression for this complete codec. compression_stats() returns this alongside byte-level ratios, linking the codec directly to the EDCM metric mathematics (§2, §11). Public API @@ -33,7 +33,7 @@ # id: edcmbone_compress # module_name: compress # module_kind: engine -# summary: lossless EDCM-aware codec for ParsedTranscript + RoundMetrics (separate bone/flesh streams, zlib entropy coding) +# summary: version 2 codec preserving source text, interleaved token records with full bone entries, and optional complete round metrics; zlib byte encoding # owner: Erin Spencer # public_surface: encode,decode,to_bytes,from_bytes,compression_stats # internal_surface: _tok_to_dict,_dict_to_tok,_metrics_to_dict,_dict_to_metrics,_build_huffman_codes,_huffman_expected_bits @@ -42,7 +42,7 @@ # network_boundary: none # user_data_boundary: none # admin_only: false -# tests: hmmm +# tests: tests.test_measurement, tests.test_audit_regressions # rollout: default_enabled # rollback: remove module; transcripts persist uncompressed # requires: edcmbone_parser_turns_rounds,edcmbone_metrics_compute @@ -53,6 +53,7 @@ from __future__ import annotations +import copy import heapq import json import math @@ -69,7 +70,7 @@ # --------------------------------------------------------------------------- # Format version — bump when encoding changes # --------------------------------------------------------------------------- -_FORMAT_VERSION = 1 +_FORMAT_VERSION = 2 # --------------------------------------------------------------------------- @@ -85,6 +86,7 @@ def _tok_to_dict(tok): "f": tok.families, "t": tok.bone_type, "n": tok.normalized, + "e": copy.deepcopy(tok.entry), } return {"k": "F", "s": tok.surface} @@ -93,11 +95,11 @@ def _dict_to_tok(rec): if rec["k"] == "B": return BoneToken( surface=rec["s"], - normalized=rec.get("n", rec["s"].lower()), + normalized=rec["n"], bone_type=rec["t"], primary=rec["p"], families=rec["f"], - entry={}, + entry=copy.deepcopy(rec["e"]), ) return FleshToken(surface=rec["s"]) @@ -124,6 +126,8 @@ def encode(parsed, metrics=None): The dict is JSON-serialisable and self-describing. Bones and flesh are interleaved in token order so reconstruction is exact. """ + if metrics is not None and len(metrics) != len(parsed.rounds): + raise ValueError("metrics must contain exactly one record per round") rounds_out = [] for i, rnd in enumerate(parsed.rounds): turns_out = [] @@ -134,12 +138,14 @@ def encode(parsed, metrics=None): "tk": [_tok_to_dict(t) for t in turn.tokens], }) rec = {"i": rnd.index, "turns": turns_out} - if metrics is not None and i < len(metrics): + if metrics is not None: rec["m"] = _metrics_to_dict(metrics[i]) rounds_out.append(rec) return { "v": _FORMAT_VERSION, + "source_text": parsed.source_text, + "metrics_present": metrics is not None, "speakers": parsed.speakers, "rounds": rounds_out, } @@ -152,11 +158,19 @@ def decode(data): ------- (ParsedTranscript, list[RoundMetrics] | None) """ + if data.get("v") != _FORMAT_VERSION: + raise ValueError("unsupported codec version; replay v1 with its original pinned producer") + if not isinstance(data.get("metrics_present"), bool): + raise ValueError("codec metrics presence must be explicit") + if data.get("source_text") is not None and not isinstance(data["source_text"], str): + raise ValueError("codec source_text must be a string or null") rounds = [] all_turns = [] metrics_out = [] for rec in data["rounds"]: + if ("m" in rec) != data["metrics_present"]: + raise ValueError("codec metrics must cover all rounds or none") turns = [] for trec in rec["turns"]: tokens = [_dict_to_tok(t) for t in trec["tk"]] @@ -170,8 +184,8 @@ def decode(data): if "m" in rec: metrics_out.append(_dict_to_metrics(rec["m"])) - pt = ParsedTranscript(rounds=rounds, turns=all_turns) - return pt, (metrics_out if metrics_out else None) + pt = ParsedTranscript(rounds=rounds, turns=all_turns, source_text=data["source_text"]) + return pt, (metrics_out if data["metrics_present"] else None) # --------------------------------------------------------------------------- diff --git a/edcm/measurement/parser/turns_rounds.py b/edcm/measurement/parser/turns_rounds.py index d6d472f1..551807a8 100644 --- a/edcm/measurement/parser/turns_rounds.py +++ b/edcm/measurement/parser/turns_rounds.py @@ -29,7 +29,7 @@ # network_boundary: none # user_data_boundary: none # admin_only: false -# tests: tests.test_apostrophe_normalization_and_tokenization +# tests: tests.test_measurement, tests.test_audit_regressions # rollout: default_enabled # rollback: remove module; transcripts cannot be parsed into the EDCM structure # requires: edcmbone_canon_loader @@ -132,9 +132,12 @@ def __repr__(self): class ParsedTranscript: """Full parse result.""" - def __init__(self, rounds, turns): + def __init__(self, rounds, turns, source_text=None): self.rounds = rounds self.turns = turns + # Exact input, including labels, spacing and line endings. None means + # a caller constructed the parsed object without supplying source text. + self.source_text = source_text self.speakers = _ordered_unique(t.speaker for t in turns) # convenience ------------------------------------------------------- @@ -161,28 +164,46 @@ def __repr__(self): # Patterns tried in order; each must have a named group "speaker" and "text". _TURN_PATTERNS = [ # **Speaker**: text (markdown bold) - re.compile(r"^\*\*(?P[^*]+)\*\*\s*:\s*(?P.+)$", re.MULTILINE), + re.compile(r"^\*\*(?P[^*\r\n]+)\*\*[ \t]*:[ \t]*(?P.*)$"), # [Speaker]: text - re.compile(r"^\[(?P[^\]]+)\]\s*:\s*(?P.+)$", re.MULTILINE), + re.compile(r"^\[(?P[^\]\r\n]+)\][ \t]*:[ \t]*(?P.*)$"), # Speaker (role): text - re.compile(r"^(?P[A-Za-z][A-Za-z0-9 _\-]{0,30})\s*\([^)]*\)\s*:\s*(?P.+)$", re.MULTILINE), + re.compile(r"^(?P[A-Za-z][A-Za-z0-9 _\-]{0,30})[ \t]*\([^)]*\)[ \t]*:[ \t]*(?P.*)$"), # Speaker: text (plain label — shortest reliable last) - re.compile(r"^(?P[A-Za-z][A-Za-z0-9 _\-]{0,30})\s*:\s*(?P.+)$", re.MULTILINE), + re.compile(r"^(?P[A-Za-z][A-Za-z0-9 _\-]{0,30})[ \t]*:[ \t]*(?P.*)$"), ] def _split_turns(text): - """Return list of (speaker, text) pairs from a raw transcript string.""" - for pattern in _TURN_PATTERNS: - matches = list(pattern.finditer(text)) - if len(matches) >= 2: - return [(m.group("speaker").strip(), m.group("text").strip()) for m in matches] + """Retain every line; a recognized label starts a turn in any format. - # Fallback: treat the whole transcript as one anonymous turn - stripped = text.strip() - if stripped: - return [("SPEAKER", stripped)] - return [] + Unlabelled lines continue the current turn. Preamble has speaker SPEAKER. + Label-like lines are syntax, not inferred speaker identities; callers must + disambiguate prose that has that form. Exact label bytes live in source_text. + """ + if not text.strip(): + return [] + turns = [] + speaker = "SPEAKER" + chunks = [] + labelled = False + for line in text.splitlines(keepends=True): + body = line.rstrip("\r\n") + ending = line[len(body):] + match = next((m for pattern in _TURN_PATTERNS if (m := pattern.fullmatch(body))), None) + if match: + if chunks or labelled: + turns.append((speaker, "".join(chunks))) + speaker = match.group("speaker").strip() + if not speaker: + raise ValueError("speaker label must be non-empty") + chunks = [match.group("text") + ending] + labelled = True + else: + chunks.append(line) + if chunks or labelled: + turns.append((speaker, "".join(chunks))) + return turns # --------------------------------------------------------------------------- @@ -384,7 +405,8 @@ def parse_transcript(transcript, round_strategy="cycle", canon=None): transcript : str Raw text. Speaker turns must be prefixed with a label followed by a colon, e.g. ``A: hello`` or ``**User**: hello``. Multiple - recognised formats are tried automatically. + recognised formats may be mixed. Unlabelled lines continue the previous + turn; preamble is retained as SPEAKER. source_text retains the exact input. round_strategy : "cycle" | "pairs" How to group turns into rounds. "cycle" (default) — a round ends when the anchor speaker (first @@ -399,6 +421,10 @@ def parse_transcript(transcript, round_strategy="cycle", canon=None): ------- ParsedTranscript """ + if not isinstance(transcript, str): + raise TypeError("transcript must be a string") + if round_strategy not in ("cycle", "pairs"): + raise ValueError("round_strategy must be cycle or pairs") if canon is None: canon = CanonLoader() @@ -412,7 +438,7 @@ def parse_transcript(transcript, round_strategy="cycle", canon=None): turns.append(Turn(speaker, text, classified)) rounds = _group_into_rounds(turns, strategy=round_strategy) - return ParsedTranscript(rounds=rounds, turns=turns) + return ParsedTranscript(rounds=rounds, turns=turns, source_text=transcript) # --------------------------------------------------------------------------- diff --git a/edcm/shared_stack.py b/edcm/shared_stack.py index c77f577d..6ffa3fd2 100644 --- a/edcm/shared_stack.py +++ b/edcm/shared_stack.py @@ -10,9 +10,10 @@ separate compartments. ``epoch_identity`` changes when the METAPAT canon/provenance identity, UCNS -profile configuration, EDCM policy manifest, or selected implementation -changes. ``result_identity`` additionally binds source evidence, exact profile -observations, readouts, and any independently attached evidence. +profile configuration, result schema, EDCM policy manifest, or selected implementation +changes. ``result_identity`` binds every emitted field except its own digest. +Public raw inputs enter through the layer pipeline; this module assembles trusted +in-process layer state and does not authenticate producers. """ # === MODULE_BUILD === @@ -22,13 +23,13 @@ # summary: deterministic final EDCM result contract separating source evidence, METAPAT semantic authority, exact UCNS word-gonol observations, typed UCNS geometry and factorization absence, EDCM policy identity, implementation provenance, readouts/NA, unresolved constraints, and attachment states. # owner: Erin Spencer # public_surface: RESULT_SCHEMA_ID, RESULT_SCHEMA_VERSION, EDCMResultContract, build_result_contract -# internal_surface: _canonical_bytes, _digest, _source_evidence, _typed_absence, _readouts, _collect_unresolved +# internal_surface: _canonical_bytes, _digest, _source_evidence, _typed_absence, _readouts, _validate_measurement, _collect_unresolved # auth_boundary: none # storage_boundary: no persistence; emits deterministic JSON-compatible records # network_boundary: none # user_data_boundary: hashes caller transcript content and preserves caller source reference without external transmission # admin_only: false -# tests: tests.test_shared_stack_contract, tests.test_ucns_adapter +# tests: tests.test_shared_stack_contract, tests.test_ucns_adapter, tests.test_audit_regressions # rollout: default_enabled # rollback: remove the profile-observation compartment and restore the prior result schema only with a versioned migration # requires: edcmucns_manifest, edcm_metapat_adapter, edcm_ucns_adapter, edcm_measurement @@ -40,13 +41,14 @@ import hashlib import json +import math from dataclasses import asdict, dataclass from typing import Any, Mapping from .edcmucns.manifest import PolicyManifest RESULT_SCHEMA_ID = "edcm.shared-stack-result" -RESULT_SCHEMA_VERSION = "1.2.0" +RESULT_SCHEMA_VERSION = "2.0.0" def _canonical_bytes(value: Any) -> bytes: @@ -55,6 +57,7 @@ def _canonical_bytes(value: Any) -> bytes: ensure_ascii=False, sort_keys=True, separators=(",", ":"), + allow_nan=False, ).encode("utf-8") @@ -90,7 +93,7 @@ def _source_evidence(payload: Mapping[str, Any]) -> dict[str, Any]: def _readouts(payload: Mapping[str, Any]) -> dict[str, Any]: - measured = "rounds" in payload + measured = payload.get("measurement_computed") is True if not measured: return { "state": "NA", @@ -106,6 +109,7 @@ def _readouts(payload: Mapping[str, Any]) -> dict[str, Any]: "structural_density", ), } + _validate_measurement(payload) return { "state": "measured", "rounds": payload.get("rounds"), @@ -116,6 +120,39 @@ def _readouts(payload: Mapping[str, Any]) -> dict[str, Any]: } +def _validate_measurement(payload: Mapping[str, Any]) -> None: + """Validate completed layer state; this is not producer authentication.""" + def bounded(value: Any, low: float = 0.0) -> bool: + return (isinstance(value, (int, float)) and not isinstance(value, bool) + and math.isfinite(value) and low <= value <= 1.0) + + transcript = payload.get("transcript") + rounds, projections, alerts = (payload.get(name) for name in ("rounds", "agent_metrics", "alerts")) + if not isinstance(transcript, str) or not transcript.strip(): + raise ValueError("completed measurement requires a non-empty source transcript") + if not isinstance(rounds, list) or not rounds: + raise ValueError("completed measurement requires non-empty rounds") + if not all(isinstance(rows, list) and len(rows) == len(rounds) for rows in (projections, alerts)): + raise ValueError("measurement projections and alerts must cover every round") + if not bounded(payload.get("structural_density")): + raise ValueError("measurement structural density must be finite and bounded") + axes = ("C", "R", "F", "E", "D", "N", "I", "O", "L", "P", "kappa", "dissonance_energy") + for index, (row, projection, flags) in enumerate(zip(rounds, projections, alerts, strict=True)): + if not isinstance(row, Mapping) or not isinstance(projection, Mapping): + raise ValueError("measurement records must be mappings") + if any(type(record.get("round_index")) is not int or record["round_index"] != index + for record in (row, projection)): + raise ValueError("measurement round indices must be complete and ordered") + if not all(bounded(row.get(axis), -1.0 if axis == "O" else 0.0) for axis in axes): + raise ValueError("measurement axes must be present, finite and bounded") + if not all(type(row.get(key)) is int and row[key] >= 0 for key in ("token_count", "bone_count")): + raise ValueError("measurement counts must be nonnegative integers") + if not all(bounded(projection.get(axis)) for axis in ("CM", "DA", "DRIFT", "DVG", "INT", "TBF")): + raise ValueError("measurement projections must be present, finite and bounded") + if not isinstance(flags, list) or not all(isinstance(flag, str) for flag in flags): + raise ValueError("measurement alerts must be a list of names per round") + + def _collect_unresolved(payload: Mapping[str, Any]) -> tuple[str, ...]: unresolved: list[str] = [] semantics = payload.get("metapat_semantics") @@ -161,7 +198,13 @@ def build_result_contract( payload: Mapping[str, Any], manifest: PolicyManifest, ) -> EDCMResultContract: - """Build the deterministic final contract from completed layer state.""" + """Build from completed, trusted in-process layer state, not raw input. + + Use build_default_layers().run() for public input validation. Python callers + controlling layer implementations remain trusted; hashes are not signatures. + """ + if any(key in payload for key in ("ucns_geometry", "ucns_factorization_evidence")): + raise ValueError("unsupported geometry or factorization evidence in result state") source = _source_evidence(payload) metapat = payload.get("metapat_semantics") @@ -182,23 +225,14 @@ def build_result_contract( else: profile_record = {"state": "attached", **dict(profile_observation)} - ucns_geometry = payload.get("ucns_geometry") - if not isinstance(ucns_geometry, Mapping): - geometry_record = _typed_absence( - "ucns_geometry_identity", - "the EDCM word-gonol observation profile does not supply UCNS geometry", - ) - else: - geometry_record = {"state": "attached", **dict(ucns_geometry)} - - factorization = payload.get("ucns_factorization_evidence") - if not isinstance(factorization, Mapping): - factorization_record = _typed_absence( - "ucns_factorization_evidence", - "no validated UCNS factorization evidence was attached", - ) - else: - factorization_record = {"state": "attached", **dict(factorization)} + geometry_record = _typed_absence( + "ucns_geometry_identity", + "the EDCM word-gonol observation profile does not supply UCNS geometry", + ) + factorization_record = _typed_absence( + "ucns_factorization_evidence", + "no factorization producer is authorized by this profile", + ) manifest_record = { "schema": "edcm.policy-manifest.v031", @@ -241,6 +275,7 @@ def build_result_contract( unresolved = _collect_unresolved(payload) epoch_fields = { + "result_schema_version": RESULT_SCHEMA_VERSION, "metapat_canon_digest": metapat_record.get("canon_digest"), "metapat_provenance_digest": metapat_record.get("provenance_digest"), "ucns_profile_id": profile_record.get("profile_id"), @@ -254,22 +289,10 @@ def build_result_contract( "measurement_implementation": implementation.get("measurement"), } epoch_identity = _digest(epoch_fields) - result_identity = _digest( - { - "epoch_identity": epoch_identity, - "source_evidence": source, - "ucns_profile_observation": profile_record, - "readouts": readouts, - "ucns_factorization_evidence": factorization_record, - "status_evidence": status_evidence, - } - ) - - return EDCMResultContract( + result_fields = dict( schema_id=RESULT_SCHEMA_ID, schema_version=RESULT_SCHEMA_VERSION, epoch_identity=epoch_identity, - result_identity=result_identity, source_evidence=source, metapat_semantic_constraints=metapat_record, ucns_profile_observation=profile_record, @@ -281,6 +304,7 @@ def build_result_contract( status_evidence=status_evidence, unresolved_constraints=unresolved, ) + return EDCMResultContract(result_identity=_digest(result_fields), **result_fields) __all__ = [ diff --git a/edcm/ucns_adapter.py b/edcm/ucns_adapter.py index 4902cfad..74459690 100644 --- a/edcm/ucns_adapter.py +++ b/edcm/ucns_adapter.py @@ -1189,6 +1189,8 @@ def normalize(self, payload: Mapping[str, Any]) -> dict[str, Any]: + ", ".join(legacy) ) + # Unsupported geometry never survives an early return without turns. + state.pop("ucns_geometry", None) raw_turns = state.get("ucns_turns") if raw_turns is None: state["ucns_integration"] = self.status.as_dict() diff --git a/edcm/ucns_edcm_experiments.py b/edcm/ucns_edcm_experiments.py index 1621f8ba..b01e8b59 100644 --- a/edcm/ucns_edcm_experiments.py +++ b/edcm/ucns_edcm_experiments.py @@ -51,7 +51,7 @@ PROGRAM_SCHEMA = "edcm.ucns-edcm-experiment-report/0.1.0" PROGRAM_VERSION = "0.1.0" EXPECTED_UCNS_COMMIT = "5331ae9a4cf7eddfa1de72b8caed28e2358cc0ed" -BASELINE_CANDIDATE_ID = "edcm-measurement-v1" +BASELINE_CANDIDATE_ID = "edcm-measurement-v2" CONTRASTIVE_CANDIDATE_ID = "edcm-contrastive-v0" @@ -964,7 +964,7 @@ def run_default_experiments( verdicts = tuple(_evaluate_relation(relation, index, comparison) for relation in relations) findings = _policy_findings(structural, index, comparison) candidate_identities = ( - (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.1.0"), + (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.2.0"), (CONTRASTIVE_CANDIDATE_ID, "The-Interdependency/edcm:edcm.ucns_edcm_experiments"), ("ucns-candidate-pack", f"The-Interdependency/ucns@{verified_ucns_commit}"), ("comparison-policy", "ucns-edcm-combined/1(rel=1e-9,abs=1e-12)"), diff --git a/edcm/ucns_edcm_experiments_v2.py b/edcm/ucns_edcm_experiments_v2.py index a8f444fb..b9e4edd8 100644 --- a/edcm/ucns_edcm_experiments_v2.py +++ b/edcm/ucns_edcm_experiments_v2.py @@ -685,7 +685,7 @@ def _candidate_values_for_case( case.case_id, tuple((f"{prefix}.{key}", value) for key, value in sorted(values.items())), ( - "The-Interdependency/edcm:edcm/measurement@0.1.0" + "The-Interdependency/edcm:edcm/measurement@0.2.0" if candidate_id == BASELINE_CANDIDATE_ID else "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v2" ), @@ -928,7 +928,7 @@ def run_v2_experiments( True, cases, ( - (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.1.0"), + (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.2.0"), ( OCCURRENCE_CANDIDATE_ID, "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v2", diff --git a/edcm/ucns_edcm_experiments_v3.py b/edcm/ucns_edcm_experiments_v3.py index 99c513e3..861eda4c 100644 --- a/edcm/ucns_edcm_experiments_v3.py +++ b/edcm/ucns_edcm_experiments_v3.py @@ -583,7 +583,7 @@ def _scope_signatures(case: ExperimentCase, support_policy: str, ucns_api: Mappi def _candidate_values_for_case(case: ExperimentCase, ucns_api: Mapping[str, Any]) -> tuple[list[CandidateReadout], list[ScopeSignatureRecord], tuple[ScopeEvent, ...]]: readouts: list[CandidateReadout] = [] for candidate_id, prefix, evaluator, identity in ( - (BASELINE_CANDIDATE_ID, "edcm.baseline", baseline_readout, "The-Interdependency/edcm:edcm/measurement@0.1.0"), + (BASELINE_CANDIDATE_ID, "edcm.baseline", baseline_readout, "The-Interdependency/edcm:edcm/measurement@0.2.0"), (OCCURRENCE_CANDIDATE_ID, "edcm.occurrence", occurrence_coverage_readout, "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v2"), (SCOPE_CANDIDATE_ID, "edcm.scope", scope_assertion_readout, "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v3"), ): @@ -677,7 +677,7 @@ def run_v3_experiments(*, edcm_commit: str | None = None, ucns_commit: str = EXP cases, tuple(all_events), ( - (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.1.0"), + (BASELINE_CANDIDATE_ID, "The-Interdependency/edcm:edcm/measurement@0.2.0"), (OCCURRENCE_CANDIDATE_ID, "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v2"), (SCOPE_CANDIDATE_ID, "The-Interdependency/edcm:edcm.ucns_edcm_experiments_v3"), ("ucns-scope-candidate-packs", f"The-Interdependency/ucns@{verified_commit}"), diff --git a/edcm/ucns_edcm_experiments_v4.py b/edcm/ucns_edcm_experiments_v4.py index 3b46fbda..47586e2d 100644 --- a/edcm/ucns_edcm_experiments_v4.py +++ b/edcm/ucns_edcm_experiments_v4.py @@ -855,9 +855,9 @@ def run_v4_experiments( for case in cases: try: baseline = baseline_readout(case.source) - readouts.append(CandidateReadout(BASELINE_CANDIDATE_ID, case.source.case_id, tuple((f"edcm.baseline.{key}", value) for key, value in sorted(baseline.items())), "The-Interdependency/edcm:edcm-measurement-v1")) + readouts.append(CandidateReadout(BASELINE_CANDIDATE_ID, case.source.case_id, tuple((f"edcm.baseline.{key}", value) for key, value in sorted(baseline.items())), "The-Interdependency/edcm:edcm-measurement-v2")) except Exception as exc: - readouts.append(CandidateReadout(BASELINE_CANDIDATE_ID, case.source.case_id, (), "The-Interdependency/edcm:edcm-measurement-v1", f"{type(exc).__name__}: {exc}")) + readouts.append(CandidateReadout(BASELINE_CANDIDATE_ID, case.source.case_id, (), "The-Interdependency/edcm:edcm-measurement-v2", f"{type(exc).__name__}: {exc}")) try: scope = scope_assertion_readout(case.source) readouts.append(CandidateReadout("edcm-scope-assertion-v1", case.source.case_id, tuple((f"edcm.scope.{key}", value) for key, value in sorted(scope.items())), "The-Interdependency/edcm:edcm-scope-assertion-v1")) diff --git a/edcm_msdmd.ts b/edcm_msdmd.ts index ebc31ef8..2e71268b 100644 --- a/edcm_msdmd.ts +++ b/edcm_msdmd.ts @@ -2,28 +2,6 @@ import { defineMsdmdCollection } from "./.agents/skills/msdmd/collection"; export default defineMsdmdCollection({ "declarations": [ - { - "block": "MODULE_BUILD", - "fields": { - "admin_only": "false", - "auth_boundary": "none", - "internal_surface": "validate_report, canonical_bytes, digest", - "module_kind": "instrument", - "module_name": "portfolio_plan", - "network_boundary": "none", - "owner": "The-Interdependency/skill-lib maintainers", - "public_surface": "load_report, build_portfolio, main", - "rollback": "remove the aggregator, schemas, companion docs, and portfolio projection section without changing repo-owned source claims", - "rollout": "explicit CLI or library invocation after repo reports are supplied", - "storage_boundary": "none", - "summary": "validates repo-owned plan reports and derives a deterministic cross-repository portfolio projection without transferring authority", - "tests": "tests/test_interdependent_work_graph_portfolio_plan.py", - "unresolved": "automatic portfolio membership discovery, persistent live service, cryptographic producer authentication", - "user_data_boundary": "none" - }, - "file": ".agents/skills/interdependent-work-graph/portfolio_plan.py", - "id": "interdependent_work_graph_portfolio_plan" - }, { "block": "MODULE_BUILD", "fields": { @@ -1114,7 +1092,7 @@ export default defineMsdmdCollection({ "fields": { "admin_only": "false", "auth_boundary": "none", - "internal_surface": "_record_layer, _local_provenance", + "internal_surface": "_record_layer, _local_provenance, _reject_retired_inputs", "module_kind": "engine", "module_name": "layers", "network_boundary": "none", @@ -1126,7 +1104,7 @@ export default defineMsdmdCollection({ "since": "2026-06-02", "storage_boundary": "none", "summary": "Provenance-bearing EDCM stack with independently selected METAPAT semantic authority, exact UCNS word-gonol observation profile or typed absence, canonical local measurement, shared-stack composition, and final result-contract delivery.", - "tests": "tests.test_measurement, tests.test_ucns_adapter, tests.test_metapat_adapter, tests.test_shared_stack_contract", + "tests": "tests.test_measurement, tests.test_ucns_adapter, tests.test_metapat_adapter, tests.test_shared_stack_contract, tests.test_audit_regressions", "unresolved": "formal Mobius coordinates and higher-gonol composition remain unattached; profile observations do not supply geometry, factorization, or theorem status", "user_data_boundary": "threads caller payloads through deterministic package-local layers; transcript content is hashed in final result identity" }, @@ -1173,8 +1151,8 @@ export default defineMsdmdCollection({ "rollout": "default_enabled", "since": "2026-06-02", "storage_boundary": "none", - "summary": "lossless EDCM-aware codec for ParsedTranscript + RoundMetrics (separate bone/flesh streams, zlib entropy coding)", - "tests": "hmmm", + "summary": "version 2 codec preserving source text, interleaved token records with full bone entries, and optional complete round metrics; zlib byte encoding", + "tests": "tests.test_measurement, tests.test_audit_regressions", "unresolved": "none", "user_data_boundary": "none" }, @@ -1318,7 +1296,7 @@ export default defineMsdmdCollection({ "since": "2026-06-02", "storage_boundary": "none", "summary": "embedded rule-based transcript parser (canon-driven, no ML deps) producing bones/flesh tokens, turns, and rounds", - "tests": "tests.test_apostrophe_normalization_and_tokenization", + "tests": "tests.test_measurement, tests.test_audit_regressions", "unresolved": "none", "user_data_boundary": "none" }, @@ -1516,7 +1494,7 @@ export default defineMsdmdCollection({ "fields": { "admin_only": "false", "auth_boundary": "none", - "internal_surface": "_canonical_bytes, _digest, _source_evidence, _typed_absence, _readouts, _collect_unresolved", + "internal_surface": "_canonical_bytes, _digest, _source_evidence, _typed_absence, _readouts, _validate_measurement, _collect_unresolved", "module_kind": "schema", "module_name": "shared_stack", "network_boundary": "none", @@ -1528,7 +1506,7 @@ export default defineMsdmdCollection({ "since": "2026-07-12", "storage_boundary": "no persistence; emits deterministic JSON-compatible records", "summary": "deterministic final EDCM result contract separating source evidence, METAPAT semantic authority, exact UCNS word-gonol observations, typed UCNS geometry and factorization absence, EDCM policy identity, implementation provenance, readouts/NA, unresolved constraints, and attachment states.", - "tests": "tests.test_shared_stack_contract, tests.test_ucns_adapter", + "tests": "tests.test_shared_stack_contract, tests.test_ucns_adapter, tests.test_audit_regressions", "unresolved": "UCNS observation digests provide content identity but not signed producer authentication; profile observations do not supply formal geometry", "user_data_boundary": "hashes caller transcript content and preserves caller source reference without external transmission" }, @@ -6302,13 +6280,6 @@ export default defineMsdmdCollection({ "source_id": "edcmucns_validation", "to": "edcmucns_types" }, - { - "from": "interdependent_work_graph_portfolio_plan", - "kind": "owns", - "source_block": "MODULE_BUILD", - "source_id": "interdependent_work_graph_portfolio_plan", - "to": "The-Interdependency/skill-lib maintainers" - }, { "from": "recovered_dissonance_controlled_gate", "kind": "owns", diff --git a/llms.txt b/llms.txt new file mode 100644 index 00000000..b41adb1b --- /dev/null +++ b/llms.txt @@ -0,0 +1,16 @@ +# LLM Instructions for edcm + +## Project Overview +EDCM owns measurement/evaluation only. Package 0.2.0 supplies candidate edcm-measurement-v2, result schema 2.0.0 and codec 2. Frozen v1 canon data and historical reports retain their exact identities. UCNS owns gonol objects, constructors and geometry; Stack owns active language construction; METAPAT owns its semantic contracts. No proof or empirical status transfers. + +## Key Definitions (never infer or expand these) +- **NA** = Required evidence, context, geometry, or authority is unavailable; never numeric zero +- **hmmm** = An unresolved constraint carried forward rather than guessed + +## Architecture Summary +The public pipeline validates raw inputs, selects independent METAPAT and UCNS adapters, measures transcripts with edcm.measurement, and assembles a complete hashed result. Optional absence is typed. UCNS geometry and factorization remain NA. Current language construction belongs to Stack/UCNS; retained EDCM construction modules serve historical replay. + +## How to Use This Repo with LLMs / Agents +Read CANON.md, CLAUDE.md, docs/GONOL_LANGUAGE_BOUNDARY.md and docs/migrations/0.2.0-audit-repair.md. Submit raw inputs to build_default_layers().run(); output-only and retired inputs fail closed. For active language construction start in the owning Stack workspace using UCNS constructors. Historical replay uses exact original EDCM and producer commits. Preserve NA != 0 and unresolved hmmm. + +This file is the single source of truth. If something is not explicitly stated in the files listed above, it does not exist in this repository. diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py new file mode 100644 index 00000000..4d89c5c0 --- /dev/null +++ b/tests/test_audit_regressions.py @@ -0,0 +1,136 @@ +"""Regression witnesses for the 2026-09-17 audit. + +Usage: python -m pytest -q tests/test_audit_regressions.py +Base-mode cases always run; installed producer cases require the full-stack extra. +""" + +import hashlib +import json + +import pytest + +import edcm.layers as layers_module +from edcm import compute_transcript, parse_transcript +from edcm.edcmucns import PolicyManifest +from edcm.measurement import compress +from edcm.metapat_adapter import MetapatAdapterSelection, missing_metapat_status +from edcm.shared_stack import build_result_contract +from edcm.ucns_adapter import REJECTED_LEGACY_INPUTS, UCNSAdapterSelection, missing_ucns_status + + +@pytest.fixture(params=["base", "full-stack"]) +def pipeline(request, monkeypatch): + if request.param == "base": + monkeypatch.setattr(layers_module, "select_metapat_adapter", lambda: MetapatAdapterSelection(None, missing_metapat_status())) + monkeypatch.setattr(layers_module, "select_ucns_adapter", lambda: UCNSAdapterSelection(None, missing_ucns_status())) + else: + pytest.importorskip("metapat") + pytest.importorskip("ucns") + return layers_module.build_default_layers() + + +def test_multiline_refusal_is_retained_and_measured(): + plain = "A: Here is the plan.\nB: Accepted." + source = "A: Here is the plan.\nI cannot do this.\nB: Accepted." + parsed = parse_transcript(source) + assert "I cannot do this." in parsed.turns[0].text + assert parsed.source_text == source + assert compute_transcript(parsed)[0].token_count > compute_transcript(parse_transcript(plain))[0].token_count + assert compute_transcript(parsed)[0].vector() != compute_transcript(parse_transcript(plain))[0].vector() + + +def test_mixed_speaker_formats_and_preamble_keep_every_turn(): + source = "Context before labels.\r\n**A**: first\r\nB: second\r\n[A]: third\r\nB (assistant): fourth" + parsed = parse_transcript(source) + assert [t.speaker for t in parsed.turns] == ["SPEAKER", "A", "B", "A", "B"] + assert [t.text.strip() for t in parsed.turns] == ["Context before labels.", "first", "second", "third", "fourth"] + assert parsed.source_text == source + + +def test_empty_speaker_line_does_not_consume_next_speaker(): + parsed = parse_transcript("A:\nB: hello\ncontinued") + assert [t.speaker for t in parsed.turns] == ["A", "B"] + assert "continued" in parsed.turns[1].text + + +@pytest.mark.parametrize("field", ["rounds", "agent_metrics", "alerts", "structural_density", "measurement_computed", "layer_provenance", "edcm_result", "ucns_geometry"]) +def test_public_pipeline_rejects_output_fields(pipeline, field): + with pytest.raises(ValueError, match="output-only"): + pipeline.run({field: []}) + + +@pytest.mark.parametrize("field", sorted(REJECTED_LEGACY_INPUTS)) +def test_retired_inputs_fail_in_all_modes(pipeline, field): + with pytest.raises(ValueError, match="retired"): + pipeline.run({field: {"made_up": True}}) + + +def test_direct_measurement_clears_stale_outputs(): + state = layers_module.ConsolidatedMeasurementLayer().measure({"rounds": [{"P": 1}], "measurement_computed": True}) + assert "rounds" not in state + contract = build_result_contract(state, PolicyManifest()) + assert contract.readouts["state"] == "NA" + + +def test_result_builder_does_not_infer_execution_from_rounds(): + contract = build_result_contract({"rounds": [{"P": 1}]}, PolicyManifest()) + assert contract.readouts["state"] == "NA" + + +@pytest.mark.parametrize("field", ["ucns_geometry", "ucns_factorization_evidence"]) +def test_result_builder_rejects_unsupported_evidence(field): + with pytest.raises(ValueError, match="unsupported"): + build_result_contract({field: {"claim": "arbitrary"}}, PolicyManifest()) + + +def test_result_identity_binds_every_emitted_compartment(pipeline): + contract = pipeline.run({"transcript": "A: Here is the plan.\nB: Accepted."})["edcm_result"] + identity = contract.pop("result_identity") + def digest(value): + return hashlib.sha256(json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False).encode()).hexdigest() + assert identity == digest(contract) + for field in contract: + changed = {**contract, field: {"changed": True}} + assert digest(changed) != identity, field + + +@pytest.mark.parametrize("damage", ["missing_projection", "nan", "wrong_index", "source_absent"]) +def test_result_builder_rejects_incomplete_measurements(pipeline, damage): + state = pipeline.run({"transcript": "A: Here is the plan.\nB: Accepted."}) + if damage == "missing_projection": + state["agent_metrics"] = [] + elif damage == "nan": + state["rounds"][0]["P"] = float("nan") + elif damage == "wrong_index": + state["rounds"][0]["round_index"] = 9 + else: + state.pop("transcript") + with pytest.raises(ValueError, match="measurement"): + build_result_contract(state, PolicyManifest()) + + +def test_codec_preserves_source_and_every_token_field(): + source = " **A**: here’s a plan\r\nA: here is the plan.\r\nB: Accepted.\n" + parsed = parse_transcript(source) + metrics = compute_transcript(parsed) + restored, restored_metrics = compress.from_bytes(compress.to_bytes(parsed, metrics)) + assert restored.source_text == source + assert [(t.speaker, t.text) for t in restored.turns] == [(t.speaker, t.text) for t in parsed.turns] + for before, after in zip(parsed.turns, restored.turns, strict=True): + for original, decoded in zip(before.tokens, after.tokens, strict=True): + assert type(decoded) is type(original) + for field in original.__slots__: + assert getattr(decoded, field) == getattr(original, field) + assert [m.as_dict() for m in restored_metrics] == [m.as_dict() for m in metrics] + + +def test_codec_refuses_unversioned_or_historical_lossy_payloads(): + for version in (None, 1, 99): + with pytest.raises(ValueError, match="version"): + compress.decode({"v": version, "rounds": []}) + + +def test_codec_refuses_partial_metric_lists(): + parsed = parse_transcript("A: first\nB: second\nA: third") + with pytest.raises(ValueError, match="metrics"): + compress.encode(parsed, compute_transcript(parsed)[:1]) diff --git a/tests/test_gonol_language_authority.py b/tests/test_gonol_language_authority.py index e412d2cd..020b083e 100644 --- a/tests/test_gonol_language_authority.py +++ b/tests/test_gonol_language_authority.py @@ -1,68 +1,27 @@ -from __future__ import annotations - +"""Prevent active instructions from restoring superseded construction ownership.""" from pathlib import Path - ROOT = Path(__file__).resolve().parents[1] -LIVE_SURFACES = ( - ROOT / "CANON.md", - ROOT / "README.md", - ROOT / "CLAUDE.md", - ROOT / "AGENTS.md", - ROOT / "docs" / "GONOL_LANGUAGE_BOUNDARY.md", -) - - -def _compact(path: Path) -> str: - return " ".join(path.read_text(encoding="utf-8").split()) - - -def test_live_surfaces_route_gonol_authority_consistently() -> None: - boundary = _compact(ROOT / "docs" / "GONOL_LANGUAGE_BOUNDARY.md") - canon = _compact(ROOT / "CANON.md") - agents = _compact(ROOT / "AGENTS.md") +LIVE_SURFACES = tuple(ROOT / name for name in ( + "CANON.md", "README.md", "CLAUDE.md", "AGENTS.md", "docs/GONOL_LANGUAGE_BOUNDARY.md", +)) - for text in (boundary, canon, agents): - assert "every admitted character is a gonol" in text - assert "METAPAT" in text - assert "UCNS" in text - assert "EDCM" in text - assert "METAPAT defines affixiation" in boundary - assert "UCNS owns any exact geometric realization" in boundary - assert "EDCM applies affixiation to text-domain gonols" in boundary - for text in (boundary, canon, agents): - assert "scale option sets" in text - assert "edcm.gonol" in text - assert "Once closed, a gonol is atomic at any scale" in text - assert "mandatory adjacent-scale ladder" in boundary - assert "Closed gonols may participate directly at any admissible scale" in boundary - assert "does not mutate `sys.path`" in boundary - - -def test_live_surfaces_do_not_restore_ucns_language_ownership() -> None: - forbidden = ( - "UCNS owns the gonol construction", - "UCNS lexical construction remains upstream", - "UCNS owns lexical/gonol construction surfaces", - "EDCM owns neither lexical-floor membership nor UCNS character-, word-, or definition-gonol construction", - "UCNS has authorized a Scrabble dictionary as the replacement lexical source class", - ) +def test_live_surfaces_route_active_construction_to_stack_and_ucns(): for path in LIVE_SURFACES: - text = _compact(path) - for phrase in forbidden: - assert phrase not in text, f"stale authority in {path.relative_to(ROOT)}: {phrase}" - - -def test_unresolved_ucns_operations_remain_hmmm_not_semantics() -> None: - boundary = _compact(ROOT / "docs" / "GONOL_LANGUAGE_BOUNDARY.md") - assert "Unicode names, dictionary definitions" in boundary - assert "An unresolved operation remains `hmmm`" in boundary - assert "invented carrier" in boundary - - -def test_measurement_does_not_activate_from_construction() -> None: - canon = _compact(ROOT / "CANON.md") - boundary = _compact(ROOT / "docs" / "GONOL_LANGUAGE_BOUNDARY.md") - assert "EDCM construction does not validate EDCM measurement" in boundary - assert "EDCM construction and EDCM measurement remain separate" in canon + text = " ".join(path.read_text(encoding="utf-8").split()) + assert "| UCNS | Gonol objects, constructors, and geometry |" in text, path + assert "| Stack | Active language-gonol construction research and source/admission profiles |" in text, path + assert "| EDCM | Measurement/evaluation only |" in text, path + assert "research/english-gonol" in text, path + assert "research/python-gonol" in text, path + assert "EDCM applies affixiation to text-domain gonols" not in text, path + assert "edcm.gonol" in text and "historical" in text.lower(), path + + +def test_unknown_operations_and_evaluation_validity_stay_separate(): + text = " ".join((ROOT / "docs/GONOL_LANGUAGE_BOUNDARY.md").read_text().split()) + assert "An unresolved operation remains `hmmm`" in text + assert "no universal mandatory adjacent-scale ladder" in text + assert "Construction reproducibility does not validate EDCM measurement" in text + assert "projection, information-loss account, metric, baseline, partitions" in text diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 1d952d79..5770cf2d 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -9,7 +9,7 @@ def test_public_version_is_declared() -> None: - assert edcm.__version__ == "0.1.0" + assert edcm.__version__ == "0.2.0" def test_installed_metadata_matches_public_version() -> None: diff --git a/tests/test_shared_stack_contract.py b/tests/test_shared_stack_contract.py index 7c7b77b3..332be96e 100644 --- a/tests/test_shared_stack_contract.py +++ b/tests/test_shared_stack_contract.py @@ -29,7 +29,7 @@ def test_base_mode_is_explicit_and_na_is_not_zero(monkeypatch): _force_base_mode(monkeypatch) result = layers_module.build_default_layers().run({"input": "no transcript"}) contract = result["edcm_result"] - assert contract["schema_version"] == "1.2.0" + assert contract["schema_version"] == "2.0.0" assert contract["source_evidence"]["state"] == "NA" assert contract["readouts"]["state"] == "NA" assert contract["readouts"]["structural_density"] is None From d9276ff53a250af1d8ee793a53ac2b1a853ecf82 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Thu, 17 Sep 2026 03:42:28 -0700 Subject: [PATCH 2/5] Refresh EDCM portfolio report and evidence-backed upgrade plan --- docs/work-graphs/repository-plan-report.json | 137 +++++++++---------- 1 file changed, 61 insertions(+), 76 deletions(-) diff --git a/docs/work-graphs/repository-plan-report.json b/docs/work-graphs/repository-plan-report.json index 427b6707..98b1c963 100644 --- a/docs/work-graphs/repository-plan-report.json +++ b/docs/work-graphs/repository-plan-report.json @@ -9,42 +9,35 @@ "blob_sha": "9b347b2dff7692054b571602f30ee6d00c2e7265" }, "source": { - "branch": "main", - "commit": "060d3c64e2758f4d4f4fbfd1351294faa8fc3c2b", - "generated_at": "2026-08-18", - "note": "This report describes the cited EDCM state plus the current repo-owned plan. Report-only and language-boundary documentation commits are coordination metadata; they do not upgrade measurement, empirical, proof, semantic, or canon status. The current upstream UCNS lexical program selects the xkcd constrained-English 1,000-word vocabulary as lexical-floor candidate and OEWN 2025 Core as the primary contemporary lexical-semantic corpus." + "branch": "repair/edcm-audit-contracts-20260917", + "commit": "079d62f7a78ac1fa1bbd767125efbe1df2ebdd36", + "generated_at": "2026-09-17", + "note": "Describes the cited 0.2.0 repair implementation and the current repo-owned plan. This report-only commit does not change implementation or evidence status. Current routing was checked against skill-lib dd5027d99516831c0dcb83a176a67140d3819b66 and Stack 250a0afb7077b036a6c537411d004fa095c8b24a. Proposed repairs and plans do not imply a merged release or empirical validation." }, "authority": { "owns": [ - "EDCM measurement, projection, diagnostic, and result contracts", - "EDCM-maintained baseline implementation and integrity evidence", - "EDCM experiment designs, candidate-measured results, falsification records, and evidence-state labels", - "EDCM corpus runners, receipts, provenance, and measurement-side activation boundaries", - "EDCM consumer contracts and evaluation boundaries for exact upstream gonol representations" + "EDCM measurement, projections, diagnostics, result contracts and evidence standing", + "EDCM candidate implementations, experiment designs, falsification records, source receipts and measurement-side activation boundaries" ], "does_not_own": [ - "UCNS mathematical representation canon or UCNS proof status", - "UCNS xkcd/OEWN source selection, Unicode-character-gonol identity, Mobius glyph-axis construction, morphology, word-gonol construction, definition-gonol construction, atomic closure, or direct interscale coupling law", - "METAPAT semantic or ontology validity", - "a0 runtime, agent identity, deployment, or orchestration authority", - "skill-lib organization-wide build and cross-repository workflow doctrine" + "UCNS gonol objects, constructors, geometry or proof status", + "Stack active language-gonol construction research and source/admission profiles", + "METAPAT semantic contracts or affixiation meaning", + "a0 runtime, identity, deployment or orchestration", + "skill-lib organization build and evidence doctrine" ], "non_transfer": [ - "UCNS proof status does not establish EDCM empirical validity", - "EDCM empirical fit does not establish UCNS proof status", - "candidate registration or development-fixture success does not select canon", - "integrity of the maintained baseline does not establish empirical validation", - "a UCNS gonol representation does not activate EDCM measurement or establish semantic validity", - "a definition-gonol semantic role does not establish vector-embedding equivalence or efficacy", - "historical lexical-floor-named artifacts do not restore the deprecated NGSL floor premise as current architecture", - "EDCM may not externalize intrinsic UCNS semantic relationships merely because a graph projection is convenient", - "a falsified hypothesis remains research evidence and is not repaired by relabeling status" + "UCNS or METAPAT proof status does not establish EDCM empirical validity", + "EDCM fit does not establish upstream mathematics or semantics", + "Candidate registration, fixture success, source integrity and construction replay do not select canon or establish measurement validity", + "Typed NA is not numeric zero", + "Historical evidence and falsified hypotheses retain their exact identities and standing" ] }, "portfolio_role": { - "summary": "Measure and pressure responses under declared constraints, maintain falsifiable measurement candidates and evidence states, and consume exact upstream gonol representations without treating representation as measurement validity or silently inserting token, subword, opaque-vector, whole-string-hash, pairwise-sidecar, or intermediate-scale-reopening substitutions.", - "upstream_contract": "EDCM consumes exact source evidence and pinned UCNS gonol receipts without inheriting their authority. The current upstream lexical sequence is characters -> morphology -> definitions -> recursive gonol relations, with xkcd 1,000 as floor candidate and OEWN 2025 Core as primary corpus. Relationships enter gonols and completed gonols are atomic at the next scale.", - "downstream_contract": "EDCM emits measurement artifacts, experiment findings, receipts, and explicit evidence statuses that downstream systems may consume without upgrading them.", + "summary": "Measure and evaluate declared source evidence with independent provenance, explicit information loss, typed absence and falsifiable candidates.", + "upstream_contract": "Consume exact METAPAT semantics and pinned UCNS profile evidence. Active language construction belongs to Stack using UCNS objects, constructors and geometry. Future construction evaluation requires a concrete producer receipt and separately declared projection.", + "downstream_contract": "Emit measurement artifacts, experiment findings, receipts and explicit evidence statuses without transferring upstream authority.", "reports_to": { "repository": "The-Interdependency/skill-lib", "skill": "interdependent-work-graph", @@ -52,18 +45,23 @@ } }, "status": { - "state": "active research and measurement", - "current_claim": "EDCM supports represented, candidate-measured, and experiment-supported evidence in declared scopes; canon_selection remains null and empirical validation is not established. For language, EDCM is a downstream consumer of the current UCNS atomic lexical recursion: xkcd 1,000 floor candidate, OEWN 2025 Core corpus, characters -> morphology -> definitions -> recursive gonol relations, intrinsic semantic relationships, atomic closure, scale-invariant affixiation, and permitted direct interscale coupling. Historical NGSL and Scrabble planning no longer define the active source path.", + "state": "active research and measurement; audit repair proposed", + "current_claim": "Candidate edcm-measurement-v2 repairs source retention and result boundaries. Package 0.2.0, result schema 2.0.0 and codec 2 have distinct identities. Independent empirical validity is not established; canon_selection remains null. Historical EDCM construction surfaces are replay-only.", "latest_main_milestone": { - "commit": "060d3c64e2758f4d4f4fbfd1351294faa8fc3c2b", - "description": "aligned EDCM's consumer boundary with current UCNS xkcd/OEWN atomic lexical recursion" + "commit": "ddc89a97ebbcf0a5863dad6e633b01b520e9bccf", + "description": "Audited main before the 0.2.0 repair; the proposed implementation is identified by source.commit." } }, "delivered": [ { - "surface": "frozen maintained EDCM baseline", - "status": "executable and integrity-checked candidate baseline", - "boundary": "implementation integrity is not empirical validation or final UCNS-EDCM canon" + "surface": "0.2.0 audit repair candidate", + "status": "implemented with regression witnesses for source retention, output rejection, optional-mode evidence boundaries, complete result identity, routing and codec fidelity", + "boundary": "Versioned behavior change; passing engineering gates does not validate axes or thresholds." + }, + { + "surface": "current language authority routing", + "status": "EDCM measurement/evaluation; Stack construction research; UCNS objects, constructors and geometry", + "boundary": "Historical modules remain explicit replay surfaces and confer no current construction ownership." }, { "surface": "UCNS-EDCM experiment program", @@ -85,11 +83,6 @@ "status": "sealed bounded candidate-measured holdout evidence", "boundary": "balanced-accuracy interval spans chance; sensitivity hypothesis is falsified; canon_selection remains null" }, - { - "surface": "gonol-native language consumer boundary", - "status": "documented against current UCNS atomic lexical recursion", - "boundary": "documentation does not implement upstream gonols or select an EDCM semantic metric" - }, { "surface": "OEWN 2025 lexical-floor-named experiment", "status": "sealed historical evidence and acquisition/replay precedent", @@ -97,64 +90,56 @@ } ], "active_frontier": [ - "preserve the current UCNS consumer boundary: xkcd 1,000 floor candidate; OEWN 2025 Core corpus; characters -> morphology -> definitions -> recursive gonol relations; relationships intrinsic to gonols; completed gonols atomic at the next scale", - "prepare a fail-closed EDCM consumer contract for exact source-bound UCNS atomic word, morphology, definition, and recursive-gonol receipts once the upstream producer exists", - "do not impose all-pairs materialization, external semantic-edge authority, or mandatory intermediate-scale reopening on the upstream UCNS representation", - "define the smallest preregistered EDCM evaluation that can test semantic behavior, compression, reconstruction, or other declared hypotheses without promoting architecture into efficacy", - "design the next genuinely new measurement candidate under the sealed holdout boundary rather than tuning the failed candidate", - "preserve development, validation, sealed-test, candidate, witness, and decision authority separation", - "pressure measurement candidates against real-system outcomes while retaining falsified and weak results", - "integrate METAPAT constraints only through exact semantic identities and explicit transfer limits", - "keep EDCM activation distinct from package availability, UCNS proof status, representation availability, and candidate evidence" + "Expose source spans, rule IDs, denominators and unmatched text for readout explanation", + "Preregister an independently labelled validity study for one operational target", + "Develop a separate scope/order candidate against unseen negation, quotation and attribution pairs", + "Stress recovered-dissonance dynamics beyond the four recorded controlled trajectories", + "Consume exact completed Stack construction receipts only under a declared EDCM evaluation contract" ], "next_actions": [ { - "action": "consume no new lexical semantic representation until UCNS freezes exact xkcd 1,000 and OEWN 2025 Core source receipts and emits replayable atomic gonol receipts; reject tokenizer IDs, subword units, opaque vectors, whole-string hashes, pairwise-sidecar substitution, and forced intermediate reopening", - "owner": "The-Interdependency/edcm", - "dependency": "upstream UCNS source identities and recursive producer must exist first" - }, - { - "action": "after the upstream representation exists, freeze one EDCM projection, information-loss declaration, baseline set, hypotheses, metric, aggregation, partitions, stopping rules, and falsifiers before semantic/compression/reconstruction outcome inspection", + "action": "Implement exact source span and parser-coverage accounting as the first bounded engineering upgrade", "owner": "The-Interdependency/edcm", - "dependency": "exact UCNS source identities and source-bound atomic gonol receipts" + "dependency": "Bind offsets and rule contributions to the retained exact source; retain Unicode and line-ending fidelity" }, { - "action": "freeze the next experiment packet around one genuinely new measurement candidate with preregistered hypotheses, partitions, custody, stopping rules, failure conditions, and provenance", + "action": "Freeze one new measurement target, independent label authority, baseline set, partitions, effect margin, custody and falsifier before new outcome inspection", "owner": "The-Interdependency/edcm", - "dependency": "must not tune on the sealed MultiWOZ booking test set" + "dependency": "No tuning on the sealed MultiWOZ booking test set" }, { - "action": "run the next candidate through development and validation before any sealed external test evaluation", + "action": "Evaluate one pinned completed Stack construction through a declared information-loss projection only when a useful hypothesis and producer receipt are available", "owner": "The-Interdependency/edcm", - "dependency": "new candidate and test-custody boundary must be frozen first" - }, - { - "action": "bind any METAPAT or UCNS inputs to exact source identities in experiment manifests", - "owner": "The-Interdependency/edcm", - "dependency": "producer identities and mappings must be explicit and independently checkable" + "dependency": "Stack construction owner and UCNS producer contract; do not fabricate absent geometry" } ], "blocked": [ - "EDCM semantic integration is BLOCKED until UCNS pins exact xkcd 1,000 and OEWN 2025 Core sources and emits the corrected atomic recursive gonol receipts; EDCM must not rebuild the missing upstream semantics itself" + "Formal geometry/factorization attachment remains unavailable in the current word-gonol observation profile", + "No empirical promotion of repaired v2 from historical v1 calibration or sealed negative results" ], "cross_repository_relations": [ { "repository": "The-Interdependency/ucns", - "relation": "upstream authority for xkcd/OEWN lexical source binding, Unicode-character gonols, Mobius glyph-axis word construction, morphology, semantic definition gonols, atomic closure, direct interscale coupling, and recursive gonol construction", + "relation": "Gonol object, constructor and geometry authority; optional exact observation producer", "authority_transfer": false, "proof_status_transfer": false, "measurement_status_transfer": false }, + { + "repository": "The-Interdependency/stack", + "relation": "Active language-gonol construction research and admission/source profiles; future completed receipt producer for EDCM evaluation", + "authority_transfer": false + }, { "repository": "The-Interdependency/metapat", - "relation": "optional semantic-constraint producer whose exact identities may bound interpretation", + "relation": "Independent optional semantic-constraint authority", "authority_transfer": false, "semantic_status_transfer": false, "measurement_status_transfer": false }, { "repository": "The-Interdependency/skill-lib", - "relation": "build/evidence doctrine and current scale-affixiation / atomic-closure procedural boundary; no UCNS geometry authority transfer", + "relation": "Organization build, evidence and workflow doctrine; current construction routing", "authority_transfer": false } ], @@ -167,16 +152,16 @@ "mathematics_index": "docs/EDCM_MATHEMATICS.md", "joint_experiment_program": "docs/UCNS_EDCM_EXPERIMENT_PROGRAM.md", "latest_holdout_design": "docs/experiments/2026-08-02-multiwoz-booking-outcome-holdout-design.md", - "latest_holdout_findings": "docs/experiments/2026-08-02-multiwoz-booking-outcome-holdout-findings.md" + "latest_holdout_findings": "docs/experiments/2026-08-02-multiwoz-booking-outcome-holdout-findings.md", + "audit_repair_migration": "docs/migrations/0.2.0-audit-repair.md", + "upgrade_avenues": "docs/UPGRADE_AVENUES.md", + "agent_instructions": "llms.txt" }, "hmmm": [ - "the exact upstream xkcd 1,000 and OEWN 2025 Core source receipt identities and recursive UCNS producer identity", - "the EDCM projection, information-loss accounting, metric, benchmark, and falsifier for evaluating future atomic recursive gonol representations", - "empirical validity of maintained and current candidate measurement surfaces", - "selection of any final EDCM or joint UCNS-EDCM canon", - "external custody arrangement for the next sealed test", - "human outcome-label authority and adjudication protocol for future domains", - "METAPAT activation and exact semantic constraints for measurement runs", - "generalization beyond the declared corpora and bounded experiments" + "Independent empirical validity and generalization of maintained measurement axes", + "The single next operational outcome, label adjudication authority, effect margin and test custody", + "Exact next completed construction receipt and evaluation projection", + "Signed producer authentication beyond deterministic content identity", + "Final EDCM or joint UCNS-EDCM canon selection" ] } From ac2f8653f95483a59624f675e03c00fbd962a7fb Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Thu, 17 Sep 2026 03:45:56 -0700 Subject: [PATCH 3/5] Keep transcript delimiter syntax out of utterance identities --- docs/EDCM_MATHEMATICS.md | 5 +++++ docs/migrations/0.2.0-audit-repair.md | 5 +++++ edcm/measurement/parser/turns_rounds.py | 6 ++++-- tests/test_audit_regressions.py | 11 +++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/EDCM_MATHEMATICS.md b/docs/EDCM_MATHEMATICS.md index fd41af5c..6c0c2036 100644 --- a/docs/EDCM_MATHEMATICS.md +++ b/docs/EDCM_MATHEMATICS.md @@ -72,6 +72,11 @@ line independently, retaining continuation lines and preamble. Exact raw labels, spacing and line endings are retained separately in `source_text`; turn text excludes recognized label syntax. See the [migration](migrations/0.2.0-audit-repair.md). +Turn-content boundary: one terminal line ending before the next label or at +document end is separator syntax. Interior continuation and blank lines remain +content. Exact separator bytes remain available in `source_text`; they cannot +create an utterance identity difference merely because turns were reordered. + The maintained parser supports two round partitions: - `cycle`: the first observed speaker is the anchor; a new round begins when diff --git a/docs/migrations/0.2.0-audit-repair.md b/docs/migrations/0.2.0-audit-repair.md index bced98ff..71edccff 100644 --- a/docs/migrations/0.2.0-audit-repair.md +++ b/docs/migrations/0.2.0-audit-repair.md @@ -48,6 +48,11 @@ Label-like prose is syntactically ambiguous: use a declared input convention. turn text excludes label syntax. A manually constructed parsed object may use `source_text=None` to express unavailable original source. +Turn-content boundary: one terminal line ending before the next label or at +document end is separator syntax. Interior continuation and blank lines remain +content. Exact separator bytes remain available in `source_text`; they cannot +create an utterance identity difference merely because turns were reordered. + Recompute result identities under schema 2.0.0. Do not compare old and new hashes as if they described an unchanged serialization. The whole-result hash detects content changes, not authorship, truth, or empirical validity. diff --git a/edcm/measurement/parser/turns_rounds.py b/edcm/measurement/parser/turns_rounds.py index 551807a8..3721840c 100644 --- a/edcm/measurement/parser/turns_rounds.py +++ b/edcm/measurement/parser/turns_rounds.py @@ -180,6 +180,8 @@ def _split_turns(text): Unlabelled lines continue the current turn. Preamble has speaker SPEAKER. Label-like lines are syntax, not inferred speaker identities; callers must disambiguate prose that has that form. Exact label bytes live in source_text. + A single terminal line ending separates turns (or terminates the document); + it is syntax, not utterance content. Interior blank lines remain content. """ if not text.strip(): return [] @@ -193,7 +195,7 @@ def _split_turns(text): match = next((m for pattern in _TURN_PATTERNS if (m := pattern.fullmatch(body))), None) if match: if chunks or labelled: - turns.append((speaker, "".join(chunks))) + turns.append((speaker, "".join(chunks).removesuffix("\n").removesuffix("\r"))) speaker = match.group("speaker").strip() if not speaker: raise ValueError("speaker label must be non-empty") @@ -202,7 +204,7 @@ def _split_turns(text): else: chunks.append(line) if chunks or labelled: - turns.append((speaker, "".join(chunks))) + turns.append((speaker, "".join(chunks).removesuffix("\n").removesuffix("\r"))) return turns diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 4d89c5c0..7876fb44 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -134,3 +134,14 @@ def test_codec_refuses_partial_metric_lists(): parsed = parse_transcript("A: first\nB: second\nA: third") with pytest.raises(ValueError, match="metrics"): compress.encode(parsed, compute_transcript(parsed)[:1]) + + +@pytest.mark.parametrize("ending", ["\n", "\r\n", "\r"]) +def test_turn_delimiters_do_not_create_order_signals(ending): + left = parse_transcript(f"A: first{ending}B: second") + right = parse_transcript(f"B: second{ending}A: first{ending}") + assert sorted((t.speaker, t.text) for t in left.turns) == sorted((t.speaker, t.text) for t in right.turns) + source = f"A: first{ending}continued{ending}{ending}B: second{ending}" + parsed = parse_transcript(source) + assert [t.text for t in parsed.turns] == [f"first{ending}continued{ending}", "second"] + assert parsed.source_text == source From 3cd47643a4649987e909e4ccc9f696e5495d3885 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Thu, 17 Sep 2026 03:45:58 -0700 Subject: [PATCH 4/5] Bind portfolio report to the corrected transcript boundary --- docs/work-graphs/repository-plan-report.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/work-graphs/repository-plan-report.json b/docs/work-graphs/repository-plan-report.json index 98b1c963..88e78103 100644 --- a/docs/work-graphs/repository-plan-report.json +++ b/docs/work-graphs/repository-plan-report.json @@ -10,7 +10,7 @@ }, "source": { "branch": "repair/edcm-audit-contracts-20260917", - "commit": "079d62f7a78ac1fa1bbd767125efbe1df2ebdd36", + "commit": "ac2f8653f95483a59624f675e03c00fbd962a7fb", "generated_at": "2026-09-17", "note": "Describes the cited 0.2.0 repair implementation and the current repo-owned plan. This report-only commit does not change implementation or evidence status. Current routing was checked against skill-lib dd5027d99516831c0dcb83a176a67140d3819b66 and Stack 250a0afb7077b036a6c537411d004fa095c8b24a. Proposed repairs and plans do not imply a merged release or empirical validation." }, From 0215a9fcde9557bca7b721c4576d9018b7e57b0f Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Wed, 23 Sep 2026 08:40:07 -0700 Subject: [PATCH 5/5] Correct experiment CLI fixture while retaining explicit candidate version assertion --- tests/test_ucns_edcm_experiments.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_ucns_edcm_experiments.py b/tests/test_ucns_edcm_experiments.py index 0ad0517b..9ff720c9 100644 --- a/tests/test_ucns_edcm_experiments.py +++ b/tests/test_ucns_edcm_experiments.py @@ -187,7 +187,6 @@ def test_joint_runner_preserves_no_canon(tmp_path) -> None: "test-edcm-commit", "--ucns-commit", EXPECTED_UCNS_COMMIT, - PROGRAM_VERSION, PROGRAM_SCHEMA, BASELINE_CANDIDATE_ID, "--ucns-source-root", str(source_root), ]