Skip to content

task: consolidate shared contracts and packaged-resource access #451

Open

Description

@Dong1017

Goal

Consolidate existing shared data/byte contracts and packaged-resource access into explicitly bounded namespaces. This is physical ownership cleanup, not a new contracts framework or a generic common/utils package. It closes root-level scattering and does not include an internal refactor of existing subpackages. Related: #387, #408 and #412.

PR checklist

  • C1 — Move shared data/byte contracts and retire old root modules. Put the existing canonical JSON implementation, RunSpec and claim types under inferrsi.contracts as contracts/json_v1.py, contracts/runspec.py and contracts/claim.py; replace contracts.py with that package, retaining from inferrsi.contracts import RunSpec and keeping contracts/__init__.py limited to that one public re-export so there is exactly one RunSpec initialization path. In this same PR delete root _json_v1.py, runspec.py, claim.py and contracts.py; update active consumers, exact-path policy declarations, docs and tests. Add the bounded exact-root inventory guard here; initialize it to this PR's real post-migration file set, then shrink it in every later removal PR (C2, R1, A1/A2, M1), rather than waiting until R1 to prevent new flat modules.
  • C2 — Move resource access and separate evidence rules from host I/O. Move the neutral repository-pack facade to resources/repository_packs.py (inferrsi.resources.repository_packs); put evidence segment/path rules in contracts/evidence.py (contracts.evidence) and directory creation in apps/evidence_layout.py. In this same PR delete root _repo_pack_data.py and evidence_paths.py; update consumers, manifest/technical-leaf rules, docs and tests. Keep path construction in contracts.evidence free of filesystem writes; mkdir stays only in apps.evidence_layout, with a focused test proving the split. In docs/legacy-knowledge-manifest.json, relock the technical_leaf entry for the moved file (module, file path, file_sha256, allowed_imports, top_level_shape) and repoint the catalog / infra.inspection compatibility targets from inferrsi._repo_pack_data to inferrsi.resources.repository_packs; per the manifest's resource_path_revision note this relock goes through formal architecture review. Keep the files("inferrsi").joinpath("harness", "data", "repo_packs", ...) anchor unchanged so the leaf still imports no inferrsi module, and keep resources/__init__.py import-free.

Dependencies and boundaries

C2 uses the contracts package established by C1. These two PRs must remain independently testable; do not split a move from its consumer updates. No changes to task evaluation, format retirement, model experiments, or ownership of the K02 data files. Keep package data physically under its existing Knowledge/Harness/Benchmark/Apps owners.

Acceptance

  • Canonical JSON bytes and error stages, RunSpec validation/round trips, Verdict identity and Harness re-exports retain their existing semantics.
  • Contract-package initialization imports no application or core implementation and performs no filesystem I/O; import inferrsi.contracts is safe and side-effect-free. The repository-pack facade remains a neutral read-only leaf: it must not import Harness to find data.
  • Preserve the one REPO_TYPES object and the bytes/access semantics of all seven repository packs; assert object identity across the remaining consumers (for example catalog.REPO_TYPES is resources.repository_packs.REPO_TYPES while the root shell still exists) and verify installed-wheel access outside the checkout.
  • Evidence path construction stays separate from mkdir. The retirement note lists old module paths -> new paths and states the exact external pickle/class-module-path impact, rather than adding indefinite aliases.
  • Root tracked-file inventory decreases from 27 to 23 after C1 and to 21 after C2, subject to refreshing the implementation base; record exact file lists, not just counts. The build-generated _version.py is not a tracked root business file and is allowed only as wheel metadata.

Delivery discipline

  • One implementation Claude session handles only the current PR in an isolated worktree. A second Claude session may only plan the next PR in a separate planning worktree; it must not edit source.
  • Move implementation, update all active consumers/docs/tests, and delete the corresponding old root modules in the same PR. Do not introduce permanent compatibility shells or module-registry aliases.
  • Preserve CLI command behavior, original evidence bytes, record/format contracts and isolation/security checks. Announce retired Python import/serialization module paths; historical frozen evidence remains pinned to its original commit or wheel, not rewritten.
  • Before each implementation or review handoff, refresh main and confirmed dependencies. A completed plan is not implementation or approval. No automatic merge.

Activity

  1. amy-why-3459 commented on Nov 15, 2026

    @amy-why-3459
    Collaborator

    Thanks, the scope is well bounded. I checked it against current main (1373ef8e) and found a few points to settle before C1 starts:

    1. Inventory baseline matches. src/inferrsi/ currently has exactly 27 tracked root files. C1 removes _json_v1.py, runspec.py, claim.py and contracts.py (27 → 23), and C2 removes _repo_pack_data.py and evidence_paths.py (→ 21). Files under the new contracts/ and resources/ packages are not root files, so the counts in the issue hold. There is no root-inventory guard in tests/test_module_boundaries.py today, so C1 really does introduce it.
    2. Guard ownership across sibling tasks. task: consolidate existing MindIE adapters under Apps #452 M1 removes four more root modules (mindie_*.py, _mindie_read_worker.py), and task: A-entry — canonical Apps entrypoints and application composition #408 A1 removes cli.py and arguments.py. Since the guard pins an exact file list, could the issue say that every later removal PR (C2, R1, M1, A1/A2) has to shrink the list in the same PR? Otherwise whichever PR lands second will fail the guard or quietly leave a stale entry.
    3. contracts package __init__. Today contracts.py is only a 5-line shim re-exporting RunSpec. Keeping from inferrsi.contracts import RunSpec means contracts/__init__.py will eagerly import the RunSpec module, which is fine because runspec.py imports only the stdlib. Could you keep the __init__ limited to that one re-export, so that importing contracts.evidence (C2) or the canonical-JSON module doesn't pull in anything else? That keeps the acceptance criterion "initialization imports no application or core implementation" checkable by a simple import-side-effect test.
    4. Single REPO_TYPES object. It is defined in _repo_pack_data.py (7 entries) and reaches arguments.py through catalog. After the move, please assert identity (catalog.REPO_TYPES is resources.repository_packs.REPO_TYPES), not just equality, and run the installed-wheel check from a directory outside the checkout.
    5. Pickle impact. src/ has no pickle usage, so the impact is limited to external callers holding pickled RunSpec / Verdict objects. Stating that explicitly in the retirement note (old module paths → new ones) should be enough, without adding aliases.
    6. C2 split. evidence_paths.py currently builds paths and calls mkdir(parents=True, exist_ok=True) in the same function (line 24). A focused test showing that contracts.evidence performs no filesystem writes would make the separation verifiable.
  2. amy-why-3459 commented on Nov 15, 2026

    @amy-why-3459
    Collaborator

    Thanks, the updated C1/C2 text covers the earlier points (the contracts/__init__.py scope, REPO_TYPES identity, the evidence/mkdir split test, and guard shrinking across PRs). One C2 detail is still worth stating explicitly:

    docs/legacy-knowledge-manifest.json pins the leaf as technical_leaf with module: inferrsi._repo_pack_data, file: src/inferrsi/_repo_pack_data.py, file_sha256, allowed_imports and top_level_shape. Its compatibility pairs include catalog -> inferrsi._repo_pack_data and infra.inspection -> inferrsi._repo_pack_data. Moving the file to resources/repository_packs.py therefore means relocking the module, path and SHA-256 and repointing those targets. The manifest's own K02 resource_path_revision notes that such a revision requires formal architecture review. Could C2's checklist call out that relock and review step? The resource anchor files("inferrsi").joinpath("harness", "data", "repo_packs", ...) can stay as-is, so the leaf still imports no inferrsi module. resources/__init__.py should likewise stay import-free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions