---
title: Accounting Products Design Examination
examined_at: '2026-10-23'
examiner: codex
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  rhythm-v2-docs: 28f69eb55955abb7cc53e8c70771e8f30c58d0e3
branch: agent/accounting-products-desi-exam-2
method: Independent pinned-source verification and OpenAI final authorship; existing tests inspected as evidence,
  not executed against the product applications
provenance: observed
source: Pinned inventories and implementation paths below; retained decision origins and finding evidence in
  the examined artifacts
previous_report_evidence: rhythm-v2-docs:2d0b769^:specs/accounting/products/reports/DESIGN-EXAMINATION-2026-10-23.md
  (historical report recovered for its checklist; absent at this job starting commit)
briefs:
- briefs/design/accounting-products.brief.md
- briefs/design-examination/accounting-products.brief.md
source_inventory:
  services-accounting:
  - modules/products/aws/api/**
  - modules/products/aws/products.module.ts
  - modules/products/db/**
  - modules/products/services/**
  - modules/products/export/**
  - modules/products/metadata/**
  - modules/products/tests/** (cited assertions reviewed only)
  - aws/accounting.service.ts
  - db/migrations/20261019201047_product_lock_and_held_bundle_components.sql
  - db/migrations/20261018200018_products_shared_base.sql
  - db/migrations/20261018030710_products_a12_member_pricing.sql
  - docs/accounting/products.md and its cited architecture, milestone and migration records
  react-console:
  - components/accounting-config/products/**
  - components/configuration/tax/product-type-tax-classes-panel.tsx
  - components/configuration/resources/accounting-tax.tsx
  - components/configuration/area-route.tsx
  - lib/accounting-config/product-form.ts
  - lib/accounting-config/product-accounting-form.ts
  - lib/accounting-config/product-accounting-rules.ts
  - lib/accounting/configuration/client.ts
  - lib/authz/backend-aliases.ts
  - lib/configuration/areas.ts
  dependencies:
  - 'Pinned @rhythmsoftware/macroservice-http 0.18.0: dist/health-route.js'
  - 'Pinned @rhythmsoftware/macroservice-metadata 0.26.0: object-registration.js'
verification_field_changes:
- artifact: DOM-ACC-PRD-001
  field: /implementation_evidence
  before: observed
  after: partially-observed
- artifact: DOM-ACC-PRD-001
  field: /invariants/4/enforced_at
  before:
  - service
  - database
  after:
  - service
- artifact: DOM-ACC-PRD-001
  field: /invariants/4/provenance
  before: test
  after: observed
- artifact: DOM-ACC-PRD-001
  field: /invariants/4/source
  before: services-accounting:modules/products/tests/integration/services/persistence/products.shared-base.integration.spec.js#refuses
    a product of a type registered inactive (the Events types) for every caller
  after: services-accounting:modules/products/services/persistence/products.ts:createProduct
- artifact: DOM-ACC-PRD-001
  field: /invariants/7/enforced_at
  before:
  - service
  - database
  after:
  - service
- artifact: DOM-ACC-PRD-001
  field: /invariants/7/provenance
  before: test
  after: observed
- artifact: DOM-ACC-PRD-001
  field: /invariants/7/source
  before: 'services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
    closing a cycle: B including A when A includes B'
  after: services-accounting:modules/products/services/persistence/products.ts:assertProductRules, readBundleGraph
- artifact: DOM-ACC-PRD-001
  field: /invariants/8/provenance
  before: test
  after: observed
- artifact: DOM-ACC-PRD-001
  field: /invariants/8/source
  before: services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#totals
    each component price times its quantity (ACCT-M1 D12 A2)
  after: services-accounting:modules/products/services/rules/product-rules.ts:bundleTotalsProblem; services-accounting:db/migrations/20261019201047_product_lock_and_held_bundle_components.sql:accounting.save_product
- artifact: DOM-ACC-PRD-002
  field: /invariants/3/enforced_at
  before:
  - api
  - service
  - database
  after:
  - api
  - service
- artifact: DOM-ACC-PRD-002
  field: /invariants/3/provenance
  before: test
  after: observed
- artifact: DOM-ACC-PRD-002
  field: /invariants/3/source
  before: services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
    a calculated cell in the base currency, and one whose audience has no base-currency price to convert
  after: services-accounting:modules/products/services/rules/product-rules.ts:pricesProblem
- artifact: DOM-ACC-PRD-002
  field: /invariants/4/enforced_at
  before:
  - service
  - database
  after:
  - service
- artifact: DOM-ACC-PRD-002
  field: /invariants/5/enforced_at
  before:
  - service
  - database
  after:
  - service
- artifact: DOM-ACC-PRD-004
  field: /invariants/12/enforced_at
  before:
  - service
  after: []
- artifact: DOM-ACC-PRD-004
  field: /invariants/12/source
  before: services-accounting:docs/architecture/accounting-2.0/06-integrity-model.md#The accounting is resolved
    and frozen at posting (A-1)
  after: services-accounting:docs/architecture/accounting-2.0/06-integrity-model.md#The accounting is resolved
    and frozen at posting
- artifact: DOM-ACC-PRD-004
  field: /invariants/3/enforced_at
  before:
  - service
  - database
  after:
  - service
- artifact: DOM-ACC-PRD-004
  field: /invariants/7/provenance
  before: test
  after: observed
- artifact: DOM-ACC-PRD-004
  field: /invariants/7/source
  before: services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
    fixed amounts adding up to more than the standard base price
  after: services-accounting:modules/products/services/persistence/product-accounting-setups.ts:replaceProductAccounting;
    services-accounting:modules/products/services/persistence/products.ts:updateProduct
- artifact: SCR-ACC-PRD-001
  field: /actions/5/operation_id
  before: null
  after: none (opens Commerce pricing page)
- artifact: SCR-ACC-PRD-001
  field: /actions/5/permission
  before: null
  after: accounting.products.read (list entry; no additional row-action check)
- artifact: SCR-ACC-PRD-001
  field: /actions/6/operation_id
  before: null
  after: none (browser clipboard)
- artifact: SCR-ACC-PRD-001
  field: /actions/6/permission
  before: null
  after: accounting.products.read (list entry; no additional row-action check)
- artifact: SCR-ACC-PRD-003
  field: /permission
  before: accounting.products.update to edit (Edit <kind>); accounting.products.read alone opens it read-only
    (View <kind>); accounting.product-accounting.read and .update govern the accounting cards
  after: Product update allows editing; product read without update opens the read-only editor. Accounting
    cards and saving apply their own read and update checks; this page does not provide an accounting-only
    edit mode.
- artifact: SCR-ACC-PRD-004
  field: /actions/1/permission
  before: accounting.tax-classes.delete
  after: accounting.tax-classes.update (console edit gate); accounting.tax-classes.delete (API)
- artifact: SCR-ACC-PRD-004
  field: /permission
  before: accounting.tax-classes.read to see the panel; accounting.tax-classes.update and .delete to change
    it
  after: Console tax-class view reveals the panel and tax-class edit enables both assignment and clearing.
    API reads also require product read for kinds; clearing requires tax-class delete at the route.
- artifact: STATE-ACC-PRD-005
  field: /transitions/0/provenance
  before: documented
  after: unknown
- artifact: STATE-ACC-PRD-005
  field: /transitions/0/source
  before: services-accounting:modules/products/db/pricing-audience-handovers.table.ts:pricingAudienceHandovers
  after: FND-ACC-PRD-046
- artifact: WF-ACC-PRD-001
  field: /hops/5/provenance
  before: documented
  after: observed
- artifact: WF-ACC-PRD-001
  field: /hops/5/source
  before: services-accounting:modules/products/services/confirmation-emails/confirmation-email-templates.ts
    (Order)
  after: services-accounting:modules/products/services/persistence/products.ts:createProduct
- artifact: WF-ACC-PRD-002
  field: /hops/3/anchor
  before: react-console:components/accounting-config/products/product-editor.tsx:ProductEditorProps.onSaveDomain
  after: react-console:components/accounting-config/products/product-editor.tsx:ProductEditorProps
- artifact: WF-ACC-PRD-004
  field: /hops/0/anchor
  before: 'services-accounting:docs/accounting/products.md#The domain write path: accounting.save_product and
    accounting.retire_product (D-2 B, ADR §5)'
  after: 'services-accounting:docs/accounting/products.md#The domain write path: `accounting.save_product`
    and `accounting.retire_product` (D-2 B, ADR §5)'
- artifact: WF-ACC-PRD-006
  field: /hops/3/source
  before: OQ-ACC-PRD-002
  after: FND-ACC-PRD-046
- artifact: WF-ACC-PRD-007
  field: /hops/0/provenance
  before: observed
  after: unknown
- artifact: WF-ACC-PRD-007
  field: /hops/0/source
  before: services-accounting:modules/products/export/products.dataset.ts:productsExport
  after: FND-ACC-PRD-029
- artifact: WF-ACC-PRD-007
  field: /hops/1/provenance
  before: observed
  after: unknown
- artifact: WF-ACC-PRD-007
  field: /hops/1/source
  before: services-accounting:modules/products/export/products.dataset.ts:productsExport
  after: FND-ACC-PRD-029
- artifact: WF-ACC-PRD-007
  field: /hops/2/provenance
  before: observed
  after: unknown
- artifact: WF-ACC-PRD-007
  field: /hops/2/source
  before: services-accounting:modules/products/export/products.dataset.ts:productsExport
  after: FND-ACC-PRD-029
- artifact: WF-ACC-PRD-007
  field: /implementation_evidence
  before: observed
  after: partially-observed
---

# Accounting Products Design Examination

## Continuation (pass 2)

This pass finishes the examination and final wording of the entire existing design: three domain objects, five state models, seven workflows, one service contract, four screen contracts and fifteen decision records. It also rewrites the Products responsibility entry, every design finding and all five open questions. No design artifact remains unrewritten, and no examination item is left without either verified evidence or a recorded finding.

The preceding report was absent at the starting checkout. Its historical version supplied a checklist, but several earlier corrections and final revisions had been overwritten. I independently checked those claims against the same pinned sources, restored the justified corrections, and supplied final OpenAI wording throughout the prose and structured explanatory fields. Artifact verification and initial final-text rewrites have separate commits; subsequent structured-field rewrites complete each artifact's text.

Both requested briefs are present and were read. That resolves the earlier input gap while preserving its permanent finding. The planning records still declare draft or proposed maturity; neither this examination nor observed code establishes planning approval. Named Andrew decisions retain their original authority for the choices they actually cover. Planning artifacts and other modules' responsibility text were left untouched.

## Counts Examined

| Item | Count | Qualification |
|---|---:|---|
| Design artifacts | 35 | All receive final OpenAI text |
| Products responsibility entries | 1 | Ownership, operation inventory, delegation and limits |
| Logical attributes / relationships | 43 / 7 | Checked against table and service declarations |
| Object invariants | 39 | Requirements distinguished from implemented enforcement |
| State models / transitions | 5 / 27 | One downstream transition remains unknown |
| Workflows / hops | 7 / 31 | Five hops remain unknown: a domain extension, Commerce completion and three export execution steps |
| Service operations | 21 | Eighteen HTTP operations and three database functions |
| Screens / displays / actions | 4 / 17 / 17 | Includes navigation and clipboard actions |
| Decision records | 15 | Origins retained; observations do not establish approval |
| Finding register / open questions | 49 / 5 | Fifteen design findings and every open question rewritten; seven earlier allocated finding identities recovered |
| Inference operations | 0 | No model call found; all relevant inference lists remain empty |
| Source and anchor fields / origin fields | 145 / 17 | Field occurrences, including composite sources and finding references; not a count of distinct files |

## Coverage

| Inventory | Covered / total | Evidence limit |
|---|---:|---|
| HTTP operations | 18 / 18 | Explicit routes plus generated public health operation |
| Exposed database functions | 3 / 3 | Save, retire and tax resolution |
| Owned tables | 13 / 13 | Each assigned one object home below |
| Module screens | 4 / 4 | List, creation, editor and kind-default panel |
| Declared multi-step workflows | 7 / 7 | Contract coverage includes explicitly unknown external execution |
| Deployed module state machines | 0 / 0 | Record state models are logical models |
| Module-owned queues | 0 / 0 | No local worker declaration establishes the Commerce consumer |
| Module-owned schedules | 0 / 0 | Export participation does not establish coordinator scheduling |
| Model task names | 0 / 0 | No inference artifact is needed |

| Object home | Tables |
|---|---|
| DOM-ACC-PRD-001 | product_types, products, product_bundle_components, product_bulk_pricing_rules, product_task_templates |
| DOM-ACC-PRD-002 | product_prices, pricing_audience_handovers |
| DOM-ACC-PRD-004 | product_accounting_setups, product_deferral_fixed_dates, product_deferral_relative_rules, product_revenue_splits, product_inter_entity_accounts, product_type_tax_classes |

Registration declares standard read-only product fields without enabling custom fields; the pinned registration helper defaults omitted support to disabled. The service and responsibility inventories agree on all owned objects and exposed operations. No backend integration test or browser test was run in this job; source review and existing assertions support the implementation descriptions without providing new runtime proof.

## Changes by Artifact

Every row below includes a full prose rewrite and final structured explanatory wording. Sources, decision origins, permanent identifiers and intent values are retained except for the evidence corrections enumerated in this report's frontmatter.

| Artifact | Verified correction or qualification |
|---|---|
| ADR-ACC-PRD-001 | Shared identity and domain extension ownership retain their recorded origin. |
| ADR-ACC-PRD-002 | The domain transaction requirement is retained without claiming an executed extension-failure proof. |
| ADR-ACC-PRD-003 | Application ownership checks retain their decision authority. |
| ADR-ACC-PRD-004 | Separate setup permission and version boundaries are retained. |
| ADR-ACC-PRD-005 | Version comparison and locks are qualified by insertion, deletion and independently locked defaults. |
| ADR-ACC-PRD-006 | Different omission contracts stay unresolved rather than becoming an approved choice. |
| ADR-ACC-PRD-007 | No custom-field capability is declared; observed registration does not supply new product approval. |
| ADR-ACC-PRD-008 | The atomic template claim is removed; remote persistence crosses the product commit boundary. |
| ADR-ACC-PRD-009 | Storage is separated from purchase-time execution. |
| ADR-ACC-PRD-010 | Account freezing stays a downstream posting requirement. |
| ADR-ACC-PRD-011 | The approved tax ownership direction is retained while existing assignments await cutover. |
| ADR-ACC-PRD-012 | Permanent readable identity and legacy-record limitations are retained. |
| ADR-ACC-PRD-013 | Direct readers and handover declarations do not prove downstream realization. |
| ADR-ACC-PRD-014 | Local publication absence is observed; the external registry remains unverified. |
| ADR-ACC-PRD-015 | No revision-history or event mechanism is invented. |
| DOM-ACC-PRD-001 | Active-kind and graph checks are write validation; bundle arithmetic differs by entry point; remote confirmation and graph concurrency have separate limits. |
| DOM-ACC-PRD-002 | Physical keys, price modes, backing cells, window overlap and unverified handover completion are distinguished. |
| DOM-ACC-PRD-004 | Setup ownership, reference scope, share validation and optional price bounds are qualified; posted-account preservation is a downstream documented requirement. |
| SCR-ACC-PRD-001 | Retired reader navigation, price navigation, code display and clipboard behavior are included. |
| SCR-ACC-PRD-002 | No status control is invented; direct creation resolves active registered kinds while list creation offers narrower choices. |
| SCR-ACC-PRD-003 | Financial visibility and saving use separate checks; no finance-only editing mode is claimed; reload reads both records. |
| SCR-ACC-PRD-004 | Only active kinds are rendered; edit gating differs from backend delete authority and kind loading needs product read. |
| STATE-ACC-PRD-001 | Deletion has no read-version guard; invalid lifecycle actions and incomplete quick-status replacement are explained. |
| STATE-ACC-PRD-002 | Product, setup and kind-default protection have different unlock and concurrency behavior. |
| STATE-ACC-PRD-003 | An absent setup can be inserted despite a supplied version; retirement does not prohibit setup saving. |
| STATE-ACC-PRD-004 | Confirmation selection is separate from sending; remote success can survive a lost answer or later local failure. |
| STATE-ACC-PRD-005 | Stored handovers establish migration context, not an observed Commerce completion worker. |
| SVC-ACC-PRD-products | All operations, access and route permissions are covered; remote consistency, maintenance jobs and external publication are qualified. |
| WF-ACC-PRD-001 | Response assembly precedes local commit; independent template persistence has no compensation. |
| WF-ACC-PRD-002 | Console stages commit separately and retain successful baselines; first creation can remain incomplete. |
| WF-ACC-PRD-003 | Local deletion precedes best-effort template cleanup; some dependency refusals have generic error translation. |
| WF-ACC-PRD-004 | Domain rollback needs caller execution proof; SQL omission, quantity, kind and audience variants differ from HTTP; guide anchor uses the exact heading. |
| WF-ACC-PRD-005 | Grouped setup saving has one transaction, ordered product locks and request-order results. |
| WF-ACC-PRD-006 | Migration rows are observed; completion, replay and failure handling in Commerce remain unknown. |
| WF-ACC-PRD-007 | Dataset declarations are observed; orchestration, completion and failure recovery remain unknown. |
| RESP-ACC Products entry | Delegated responsibilities and invariant limits agree with the examined service and objects. |
| FINDINGS design rows and questions | Every design finding and question receives final wording; brief availability is resolved without implying approval. |
| ID_REGISTRY design entries | Titles follow the final artifacts; recovered finding allocations remain permanent and no identifier is renumbered. |

## Evidence Corrections

The frontmatter enumerates every changed protected field against the starting checkout, including its prior and final value. Product kind activity, bundle graph checks, price backing and window checks, and sellable revenue validation no longer claim general table enforcement. Expanded bundle and fixed-share statements use implementation evidence covering both entry points instead of narrow tests. Posted-account preservation has no claimed enforcement location in the setup writer, and its documentary heading is corrected.

The product object and export workflow use partially observed implementation evidence. Commerce completion and generic export execution use unknown provenance with findings; the already unknown domain extension hop stays unknown. Workflow sources and callback anchors now name actual code or the exact guide heading. Screen permissions describe implemented console gates separately from API requirements, and navigation and clipboard actions explicitly declare that they call no product operation. No approval status, intent, source pin, realization link, inference declaration or predecessor identity is advanced by this pass.

## Remaining Decisions and Proof

| Finding or question | Remaining work |
|---|---|
| FND-ACC-PRD-043 | Missing briefs are resolved; establish the planning approval baseline. |
| FND-ACC-PRD-044 / FND-ACC-PRD-038 | Assign remote-template reconciliation and acceptable lock duration. |
| FND-ACC-PRD-045 | Decide graph concurrency and treatment of existing shares after price reductions; require validation proof where tables cannot enforce it. |
| FND-ACC-PRD-046 / FND-ACC-PRD-042 | Supply Commerce realization and downstream reader contracts and execution evidence. |
| FND-ACC-PRD-047 | Resolve active-kind panel coverage and read, edit and delete permission differences. |
| FND-ACC-PRD-048 / FND-ACC-PRD-034 | Decide and test SQL versus HTTP audience, inactive-kind and quantity behavior. |
| FND-ACC-PRD-049 | Verify the external Submissions registry and any required exemption. |
| FND-ACC-PRD-027 | Prove common-record rollback after an actual domain extension failure. |
| FND-ACC-PRD-029 | Prove export execution, completeness, cutoff behavior and recovery. |
| FND-ACC-PRD-033 / FND-ACC-PRD-039 | Address browser/service validation differences and the missing setup-delete screen action. |
| FND-ACC-PRD-040 | Correct quick status actions that omit availability settings; add direct behavior proof. |
| FND-ACC-PRD-041 | Resolve the documented quote/issue tax-default difference during ownership transfer. |
| FND-ACC-PRD-035 / FND-ACC-PRD-036 / FND-ACC-PRD-037 | Add the charter's no-inference declaration in an authorized planning job, decide audit needs and verify unavailable Platform standards. |
| OQ-ACC-PRD-001 through OQ-ACC-PRD-005 | Decide tax cutover, held-audience editing, omission semantics, history and staged versus combined saving. |

The final design distinguishes required downstream behavior from locally enforced behavior. Resolving these items requires product decisions or evidence outside this job's permitted sources and edit scope; none was silently answered by rewriting planning rules.

## Validation

Dependency installation and corpus conformance pass with zero errors. All four repository tests pass. These are corpus checks; application integration, domain-consumer and browser execution remain unperformed in this job.

## Verdict for Andrew

The final design faithfully describes the locally verifiable behavior at the pinned commits and marks unproved downstream execution explicitly. Its weakest areas are independent template persistence, downstream realization and export execution, and unavailable standards and publication evidence. Before implementation preparation, establish planning approval and decide write-path parity, template recovery, tax cutover, permissions and audit requirements.
