Skip to content

Latest commit

 

History

History
553 lines (455 loc) · 23.8 KB

File metadata and controls

553 lines (455 loc) · 23.8 KB
title Implementation Working Agreement
summary Execution rules for shaping, verifying, refactoring, and committing repo work.
doc_type standard
audience human
owner repo
status active
naming_scope repo_policy
nav_order 20

Use this document when actively coding in the repo. It is the execution contract for how work should be shaped, verified, refactored, and committed so future sessions do not depend on repeated reminders from the user.

This document complements:

  • docs/standards/engineering.md for placement and modularity rules
  • docs/standards/commits.md for commit format and commit-boundary policy
  • docs/concepts/reconciliation-tax-architecture.md for architecture direction
  • docs/status/migration-sequence.md for no-big-bang migration order

Repo-Native Tooling To Use

This repo uses the external environment at $(HOME)/.venvs/tallylot-py312. Use the root Makefile as the standard local command interface. It prepends the external environment's bin/ directory to PATH, which keeps repo commands machine-neutral and sandbox-safe without inline environment prefixes.

Prefer the repo's built-in tooling before inventing local workflows:

  • inspect a fresh VS Code Problems snapshot first when the vscode-problems skill or MCP server is available, then fall back to CLI checks when the snapshot is stale, missing, or incomplete
  • bootstrap each clone with make install-hooks so the shared external environment is synced to the current checkout before hook installation; rerun that command if make cli ARGS='...' resolves a stale editable checkout after repo relocation or history rebuilds
  • run broad verification with make quality
  • run the explicit full-suite override only when it is intentionally needed with make quality-full The repo starts the standard quality gates together by default, keeps the fast pytest bundle on 4 workers by default, and reserves phased scheduling as an explicit alternate mode for comparison or debugging. Override the fast worker count only through TALLYLOT_FAST_PYTEST_WORKERS; use 0 to force serial.
  • local verification runners may apply safe autofixes to staged Python and Markdown files before validation so style-only drift is repaired locally, while CI stays read-only and reports any remaining issues directly
  • run the broad review suite locally when changing workflow, packaging, or release behavior with make pr-review-full
  • audit local CODEOWNERS coverage and live GitHub branch-protection settings together when changing delivery policy, branch protection, or CI guardrails with make audit-delivery-guardrails
  • audit PR review file-group coverage with make audit-pr-review and run the required review checks for the current diff with make pr-review
  • run the blocking flake and order-sensitivity lane with make test-stress
  • report coverage hotspots from a recent full-suite run with make coverage-hotspots
  • scaffold new adapters with make scaffold-adapter ARGS='...'
  • refresh generated pyright test-private execution environments with make sync-pyright-config when adapter-local tests/ packages are added or removed outside the scaffold tool; tools.run_quality_gates also refreshes that generated config and fails immediately when it had to update the file, so review and commit pyrightconfig.tests.json before rerunning
  • refresh adapter golden fixtures with make refresh-adapter-goldens ARGS='...'
  • benchmark test-bundle changes with make benchmark-tests
  • benchmark quality-gate scheduling changes with make benchmark-quality

Do not replace these with ad hoc shell habits when the repo already has a supported path.

Benchmark Rules

Use the repo benchmark tools only for explicit default-selection decisions.

  • benchmark one suite or quality-gate comparison set at a time
  • warm caches before measured runs
  • use warmup runs plus repeated measured iterations, then compare medians instead of one-off timings
  • benchmark both local hardware and GitHub runner classes before calling a default benchmark-backed in docs, tests, or review rationale
  • keep -n auto as a benchmark or debug candidate only; do not promote it to a repo default without fresh local and GitHub runner evidence

pyrightconfig.tests.json is generated repo policy for test-private execution environments. Do not hand-maintain adapter executionEnvironments in pyrightconfig.json; update adapter-local test package layouts and rerun the sync or quality-gate tool instead. If the quality-gate runner refreshes the generated file, commit that change and rerun the gates.

When repo-native tooling and tests need shared support:

  • keep production/runtime concerns out of tools/ and the current live repo_support/ package area
  • keep shared repo-only support in the current live repo_support/ package, not in ad hoc duplicated test helpers or tool-local path constants
  • keep tools/ focused on entry points and task-specific dev modules
  • shape forward-looking repo-only support work toward a later rename and split under dev_support/; do not expand repo_support/ as if it were the desired long-term boundary

Live repo document enforcement stays in script-owned tools, not pytest:

  • use docs-maintenance for generated sections, metadata, links, and docs-tree hygiene docs-maintenance also owns docs/README.md generated reference-group headings/order plus required naming_scope frontmatter/default enforcement
  • use target-naming for naming, locality, vocabulary, and identifier rules
  • use docs-audit for semantic repo-state document parity and cross-surface correctness docs-audit also owns forward-contract proof, owner-doc authority, and bridge cutover matrix semantics
  • keep pytest coverage for docs tooling on synthetic strings or temp repos instead of the live repo Markdown tree or live control-plane prose

Durable versus planning surfaces:

  • forward-looking docs may use ephemeral planning language when they carry planning, sequencing, or other future-oriented implementation detail; ROADMAP.md is not the only allowed planning surface
  • durable control-plane and delivery surfaces must stay phase-free and roadmap-free:
    • docs/standards/**
    • AGENTS.md
    • .claude/commands/**
    • .agents/skills/**
    • .github/pull_request_template.md
    • commit messages
    • PR titles and PR bodies
    • branch names
    • code, tooling, filenames, and generated durable examples
  • keep ordinary repo-facing tests and named examples phase-free and roadmap-free
  • synthetic tooling fixtures may intentionally mention forbidden roadmap or phase labels only when they are exercising validator or audit behavior on synthetic strings or temp repos
  • when a new live-repo docs policy needs enforcement, add it to the owning script instead of adding live-repo Markdown or control-plane prose checks to pytest

Default Coding Expectations

Agents should assume all of these are expected unless the task explicitly says otherwise:

  • keep the architecture aligned with docs/concepts/reconciliation-tax-architecture.md
  • for reconciliation, checkpoint, journal, tax, or target pipeline work, reload the owning roadmap and migration docs before shaping the change: ROADMAP.md and docs/status/migration-sequence.md
  • read the narrow forward-looking roadmap, architecture, migration, or owning boundary guidance before shaping a non-trivial change
  • refactor when a clearer shared boundary is already visible
  • extract shared components before copy-paste patterns harden
  • create or update tests alongside the implementation
  • commit at stable checkpoints without waiting to be reminded
  • do not close a non-trivial task until the verified checkpoint commit exists
  • prefer typed, explicit models over loose dictionaries and convenience code

Work Sequence

For non-trivial implementation work, use this order:

  1. confirm the target boundary and owning layer
  2. create or update the typed models, contracts, or artifact schemas first
  3. create or update tests that define the intended behavior
  4. implement the behavior
  5. refactor duplicated or cross-cutting logic into bounded shared components
  6. run the relevant quality gates
  7. checkpoint the work in a coherent commit

Do not start by patching call sites ad hoc and only later trying to discover the right structure.

Before shaping a non-trivial fix, reload the narrow forward-looking guidance that owns the change area. Prefer the intended end-state boundary over a local temporary patch when the repo already documents the target ownership model.

For reconciliation, checkpoint, journal, tax, and target pipeline work, the normal minimum routing set is:

  • docs/concepts/reconciliation-tax-architecture.md
  • ROADMAP.md
  • docs/status/migration-sequence.md

Add docs/concepts/oracle-boundaries.md and docs/concepts/transaction-classification.md when the change alters boundaries or semantic classification.

Refactor Expectations

Refactoring is expected when it clearly improves the current change, not only when the user says the word "refactor."

Refactor during the task when any of these are true:

  • the same logic is being copied into a second place
  • a module is gaining a second responsibility
  • a new feature would deepen coupling across layers
  • repeated parsing, validation, or mapping rules are visible
  • tests are getting repetitive because the production boundary is wrong
  • new work would make an existing hotspot materially worse

Do not defer an obvious structural fix if the change is already in the code you are touching and the bounded refactor is cheaper than carrying the duplication forward.

Shared Component Rules

Extract shared code only to a specific, named boundary.

Good extractions:

  • adapter-local row parsers
  • issue-rule modules
  • reconciliation decision helpers
  • tax policy mapping modules
  • journal posting assemblers
  • typed artifact writers or parsers

Avoid generic sinks:

  • helpers.py
  • utils.py
  • common.py
  • broad cross-layer convenience modules

For repo-native tooling and test support:

  • use the current live repo_support/ package only for narrow shared boundaries that are reused by multiple repo-native areas
  • do not create generic repo_support/helpers.py or repo_support/utils.py
  • if only one tool owns the logic, keep it local to that tool instead of promoting it into repo_support/
  • later implementation should rename and split this dev-only support package area under dev_support/ instead of treating repo_support/ as the final name

Shared components must stay owned by one layer and one concept.

Test-First And Structure-First Guidance

Prefer structure-first or test-first work when introducing:

  • new domain models or invariants
  • new artifact schemas
  • classification rules
  • reconciliation logic
  • journal posting rules
  • tax treatment behavior

Minimum expectation:

  • add focused unit tests for new decision logic
  • add contract tests for new external artifact parsing or rendering
  • add regression tests for fixed edge cases

Meaningful tests only:

  • add tests for user-visible behavior, real contracts, non-trivial decision logic, and fixed regressions
  • do not add trivial getter or setter tests, wording-only assertions, duplicate coverage at multiple layers, or call-order tests unless that order is the contract
  • when tests become repetitive, treat that as a signal that the production boundary may be wrong and refactor that boundary instead of piling on more near-duplicate tests
  • for repo-side agent scripts and internal workflow entry points, cover behavior in-process when a callable entry point exists and reserve subprocess tests for the real launch boundary
  • avoid duplicate in-process and subprocess tests that prove the same workflow behavior; once behavior is covered in-process, thin launch-boundary tests may use @pytest.mark.no_cover

Do not leave edge-case behavior implicit in implementation code without a test that pins it down.

Mirror test structure to production structure whenever possible:

  • tests/unit/... for business rules and local decision logic
  • tests/contract/... for artifact contracts, parsers, renderers, and command interfaces
  • tests/e2e/... only when the end-to-end workflow itself is the behavior

When a feature becomes a package, mirror that package structure in tests rather than adding a growing pile of same-prefix test files.

Commit Discipline

Agents should treat commits as part of finishing the work, not as optional afterthoughts.

Expected behavior:

  • make a commit when a bounded change is stable and verified
  • keep commits cohesive and reviewable
  • prefer one commit per coherent change, not one commit per file
  • keep each authored commit bounded to one reviewable concern with a clear rollback boundary
  • before a checkpoint commit is pushed, amend or fix up a small, scoped follow-up patch into the owning non-pushed checkpoint when that avoids a low-value micro-commit, and update the amended commit message so its Why:, What:, and Checks: sections still describe the final content
  • before creating or amending a commit, reread docs/standards/commits.md in the current task and use the installed commit template plus .git/COMMIT_EDITMSG whenever the message includes backticks, quotes, or other shell-sensitive text
  • do not use repeated amend cycles to grow one broad checkpoint that should be split into separate commits with clearer review and rollback boundaries
  • for large but separable scopes, create multiple bounded checkpoint commits before finishing instead of ending on one umbrella authored commit
  • do not bundle unrelated fixes
  • do not wait for the user to remind you to commit once the task has reached a real checkpoint
  • when a refactor spans structure, routing, tooling, and tests, checkpoint each stable change that already passes the narrow checks for that change
  • when opening a PR, use a Conventional Commit title and the structured PR body defined in docs/standards/commits.md because that metadata stays attached to the PR record and becomes the squash commit on main for the single-checkpoint exception
  • keep PR, commit, and doc language neutral and direct: Why: should state the motivating repo problem, trigger, constraint, or risk that makes the patch necessary now; What: should state the concrete repo change; and neither section should use rhetorical or promotional wording
  • before merging a PR or rewriting mainline history, verify whether the pull request record must stay attached to the merged commit; if yes, do not rewrite that merge commit after merge
  • if a multi-checkpoint PR merges with a merge commit, use <pr title> (#<pr number>) as the merge subject so the mainline log keeps the PR number visible
  • if a repair PR replaces an older pull request, mark the old PR with the repo's neutral duplicate/superseded label before closing the older PR
  • add a neutral replacement comment only when the repo has no suitable label or the user explicitly asks for explanatory prose
  • when the work uncovers follow-up or out-of-scope changes that do not belong in the current PR, search existing open issues first and create the issue immediately when no suitable issue already exists
  • open only repo-engineering follow-up issues in this repository:
    • code
    • tests
    • docs and standards
    • templates and other control-plane files
    • automation and CI
  • keep follow-up issues privacy-safe:
    • no personal information
    • no secrets or raw evidence
    • no wallet or account identifiers
    • no local absolute paths
  • use the repo-standard issue structure from docs/standards/issues.md
  • do not defer issue creation for out-of-scope work until after merge, handoff, or a later cleanup pass
  • before closing a non-trivial task, ensure the commit already exists rather than leaving commit creation as follow-up work
  • keep repo cleanup forward-only by default: do not use destructive rollback commands such as rm -rf, git restore, git reset, or git checkout -- unless the user explicitly requests that cleanup in the current thread
  • keep tracked docs, templates, and control-plane artifacts neutral and durable
  • keep durable delivery metadata and ordinary branch names phase-free and roadmap-free; use durable repo-area or behavior wording instead of planning tags
  • keep scratch review notes, temporary review ledgers, and compaction aids untracked; recover from deterministic repo facts instead

When not to commit:

  • the worktree is inconsistent
  • the tests for the change are failing
  • the checkpoint would be hard to review or roll back
  • the current diff still contains multiple separable reviewable changes

Do not collapse a broad but separable refactor into one giant commit unless the change truly cannot be reviewed or validated incrementally.

Compaction Recovery

Treat compaction or context loss as an ordinary operating condition.

When context is lost before more edits, commits, or delivery steps:

  1. reload git status and the current branch tip
  2. inspect the current diff and recent commits
  3. inspect current PR metadata and changed files when PR work is active
  4. reread only the narrow repo standards and start-skill docs for the active area
  5. reload the latest targeted verification results

Do not rely on tracked scratch notes, phase logs, or preserved review ledgers to recover task state.

Quality Gates

Default verification expectations:

  • use fresh VS Code Problems diagnostics first for instant editor-grounded lint and type feedback when they are available and current
  • targeted tests during development
  • full relevant checks before closing substantial work

Preferred commands are already defined in AGENTS.md, but the operating rule is:

  • do not call work done with only local reasoning
  • verify the changed behavior at the smallest useful level first
  • then run tools.run_quality_gates before closing the task
  • escalate to tools.run_pr_review_checks --mode full when the change touches CI, packaging, release, or other workflow areas where the local pass should mirror the final non-draft PR suite before handoff
  • avoid tools.run_quality_gates --full-tests unless you explicitly need the full-suite override rather than the standard agent path
  • do not run tools.run_quality_gates --full-tests again immediately before tools.run_pr_review_checks --mode full; the full PR-review runner already includes it
  • use tools.run_fast_pytest for an explicit fast pytest loop when you need one; the hook-owned pre-commit path now follows the staged-path planned verifier selection instead of a fixed pytest bundle

For PR review and repair loops, use tools.audit_pr_review to classify the changed file groups and use tools.run_pr_review_checks as the shared verification entrypoint:

  • draft pull-request CI always runs commit-messages and pr-metadata, then selects the remaining checks from the changed diff
  • non-draft pull-request CI switches to the full non-duplicated blocking suite plus the non-blocking coverage hotspot report lane
  • post-merge and manual CI stay change-sensitive and select only the atomic checks needed for the landed diff
  • local planned runs follow the same change-sensitive selection policy as post-merge and draft pull-request CI
  • local tools.run_pr_review_checks --mode full is the explicit broad-review override that mirrors the final non-draft PR suite for CI, packaging, release, or other workflow-sensitive changes
  • tools.run_quality_gates remains a quality-only convenience runner and does not decide PR or CI verification selection

Coverage hotspot reports are informative review output only. Use them to pick the next review target after a full-suite run; do not treat them as a replacement for correctness tests or the existing repo-wide coverage gate.

If you are changing commit-time or suite-selection policy, keep the hook path limited to bounded commit checks and use the shared quality runner or the full PR-review runner as the single broad verification source. Benchmark with tools.benchmark_tests and tools.benchmark_quality_gates when you are proposing a different test bundle or quality-gate schedule, and do not expand the hook path into a second full-suite verification pass.

Migration Discipline

When a task touches a migrating area:

  • implement on the fact-based path first
  • preserve external output projections only as needed
  • do not add new behavior to the legacy center unless required for migration
  • add parity coverage before retiring older paths

If the change would force a big-bang rewrite, the migration sequence is wrong. Split the work into a smaller compatible increment.

Workflow Integrity Rules

Keep workflow integrity rules explicit while the repo continues migrating.

  • filesystem scans that enumerate user evidence must be deterministic
  • xdist-sensitive parametrization and collection inputs must preserve deterministic ordering; do not feed unordered collections into parametrized tests that need reproducible parallel collection
  • tree-walking services should use the shared scan path with explicit output exclusions rather than ad hoc rglob() behavior
  • archive inspection, archive safety limits, and archive-member issue reporting belong in the shared intake scan layer rather than in source adapters or CLI commands
  • profiling and normalization outputs must not be written inside raw evidence trees
  • evidence references recorded in normalized or checkpoint-supporting artifacts must stay source-relative and portable across workspaces
  • docs, command routes, and agent entrypoints must stay aligned with the implemented runtime

Adapter And Artifact Discipline

When adding or changing adapters:

  • keep metadata, implementation, fixtures, and tests aligned
  • use scaffold and golden-refresh tools instead of hand-rolling repetitive layout
  • keep provider-specific parsing local to the adapter package
  • extract shared behavior only when it is truly cross-provider and conceptually stable

When adding artifacts:

  • define the schema explicitly first
  • decide whether it is a runtime artifact, output-adapter artifact, or oracle-only artifact
  • add contract coverage for parsers and renderers

User-Independent Standards

Agents should not require repeated reminders to:

  • keep layer boundaries intact
  • preserve strong typing
  • use Decimal
  • log unsupported or ambiguous facts explicitly
  • update roadmap and design docs when architecture changes
  • extract shared boundaries when duplication becomes obvious
  • add or update tests for new behavior
  • create stable checkpoint commits

These are the default operating standards for the repo.

Stop-And-Fix Triggers

Current runtime note: CoinTracking-specific semantics mentioned below describe current-edge drift to avoid, not canonical target naming.

Pause feature work and fix the structure first when:

  • a new change would require importing across a forbidden layer boundary
  • a module is becoming a new catch-all
  • a hotspot module called out in docs/standards/engineering.md is about to absorb materially new behavior without first being split
  • a flat directory would end up with more than 2 same-prefix files for one capability
  • a feature already owns a package but new helpers are being left beside it as flat sibling modules
  • CoinTracking-specific semantics are drifting into the core domain
  • bridge-era, provider, or asset-class nouns are drifting into forward-looking domain, application, id, ref, record, or directory names
  • an oracle-only artifact is being treated like a required runtime input
  • a quick patch would hide unsupported behavior instead of surfacing it

Final Pre-Close Checklist

Before closing non-trivial work, confirm:

  • the owning layer is still clear
  • shared logic is extracted to the right boundary
  • tests pin the new behavior
  • unsupported behavior is explicit
  • docs are updated if architecture or workflow changed
  • a stable checkpoint commit exists or is the immediate next step