# Scratchpad — System-Managed Default Contract Cutover

- Plan slug: `system-managed-default-contract-cutover`
- Created: `2026-03-21`

## Decisions

- (2026-03-21) Create a brand-new plan folder instead of updating `2026-03-21-client-default-contract-on-demand-routing`.
- (2026-03-21) Keep creation model on-demand at billing-configuration ensure touchpoints rather than eager create at client creation.
- (2026-03-21) Keep migration strategy lazy and deterministic; avoid broad forced backfill.
- (2026-03-21) Use hard cutover objective: remove primary-path non-contract fallback complexity once routing is stable.
- (2026-03-21) Persist explicit default-contract identity on `contracts.is_system_managed_default` and enforce uniqueness via tenant+owner-client partial unique index; deterministic naming is `System-managed default contract`.
- (2026-03-21) Centralize billing-settings row ensure in `shared/billingClients/billingSettings.ts` and make default-contract ensure part of that shared path, then route schedule/cycle-anchor/package settings/credit-expiration updates through it.
- (2026-03-21) Null client-billing-settings overrides (`settings === null`) remain delete-only and do not trigger default-contract ensure; ensure is only invoked on non-null ensure/update touchpoints.
- (2026-03-21) Add fallback client-create hook `ensureDefaultContractForClientIfBillingConfigured(...)` in shared default-contract domain and wire it into major create paths (clients package action, shared model, API service, integration import, email service) so bypass flows still reconcile when billing settings already exist.
- (2026-03-21) For API-service client deletion, enforce domain cleanup before hard delete: remove assignment/billing artifacts, then apply orphan policy to default contracts (`delete` when uninvoiced orphan, `archive` when invoiced orphan).
- (2026-03-21) Refine the target model: system-managed default contracts are attribution shells for unmatched time/usage, not recurring cadence authorities.
- (2026-03-21) Unmatched default-contract work should invoice on the client billing schedule, not on default-contract billing frequency/timing.
- (2026-03-21) System-managed default contracts should not allow contract-line authoring, recurring/service-period management, pricing-schedule authoring, or user-managed assignment date semantics.
- (2026-03-21) Add an optional client billing schedule historical bootstrap date instead of trying to encode back-dated invoiceability through default-contract assignment start dates.
- (2026-03-21) Historical bootstrap is optional, normalizes to the containing client-cycle boundary, and may move earlier only while preserving invoiced-history boundaries.

## Discoveries / Constraints

- Billing settings ensure/insert logic is duplicated across shared and package layers, so hooks must be centralized or replicated safely.
- Some client create flows bypass package-level actions (integration/email/import), so client-create hook alone is insufficient.
- API generic delete path may bypass domain cleanup used by package client delete action.
- Resolver behavior currently differs by path and can use current-time filtering instead of effective-date filtering.
- Billing engine can treat some null-assigned rows as resolvable without persisting assignment; this feeds due-work ambiguity.
- UI copy has technical/non-business labels that do not communicate default-contract behavior clearly.
- Existing package wiring tests include brittle source-string assertions for exact function signatures/throw style; those tests can fail even when runtime behavior is unchanged.
- Shared vitest config only discovers `services/**/*.test.ts` and `**/__tests__/**/*.test.ts`, so shared tests for this plan need to live under `shared/__tests__/`.
- `BaseService.delete` is generic hard-delete behavior; without `ClientService.delete` override it bypasses client-domain cleanup and can skip default-contract artifact cleanup.
- `packages/clients/src/components/clients/BillingConfiguration.tsx` general save is not the right surface for historical client-cycle bootstrap; `ClientBillingSchedule.tsx` is the existing UX entry point for schedule-specific setup.
- `shared/billingClients/createBillingCycles.ts` backfills from the current/reference cycle forward, but does not automatically create historical client cycles for back-dated work unless an explicit effective date is supplied.
- `shared/billingClients/billingSchedule.ts` and `packages/billing/src/actions/billingScheduleActions.ts` already own schedule persistence and are the natural convergence points for optional bootstrap/backfill logic.
- Blanket backdating of default-contract `client_contracts.start_date` is unsafe because contract-cadence and client-cadence recurring materialization both treat assignment start as the schedule-generation anchor/as-of boundary.
- Back-dated billable work has a parallel gap on the client-schedule side today: a new billing configuration does not automatically create historical `client_billing_cycles`, so default-contract simplification alone does not solve historical invoiceability.

## Commands / Runbooks

- Inspect prior plan scaffolds:
  - `ls -1 ee/docs/plans`
  - `ls -la ee/docs/plans/2026-03-21-client-default-contract-on-demand-routing`
- Validate new plan:
  - `jq empty ee/docs/plans/2026-03-21-system-managed-default-contract-cutover/features.json`
  - `jq empty ee/docs/plans/2026-03-21-system-managed-default-contract-cutover/tests.json`
  - `python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-03-21-system-managed-default-contract-cutover`
- Verify T001 coverage for default contract ensure:
  - `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
- Verify T002 concurrency coverage (same suite now includes forced race path):
  - `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
- (Optional) Package wiring spot-check:
  - `cd packages/billing && npx vitest run tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/billingSettingsActions.renewalDefaultsWiring.test.ts tests/billingSettingsActions.cadenceOwnerDefaultsWiring.test.ts`
- Inspect billing schedule UI/action insertion points for optional bootstrap:
  - `sed -n '1,260p' packages/clients/src/components/clients/ClientBillingSchedule.tsx`
  - `sed -n '1,260p' packages/billing/src/actions/billingScheduleActions.ts`
- Inspect historical cycle creation/bootstrap behavior:
  - `sed -n '1,320p' shared/billingClients/createBillingCycles.ts`
  - `sed -n '1,280p' shared/billingClients/billingSchedule.ts`
  - `sed -n '1,320p' packages/billing/src/actions/billingCycleActions.ts`
- Inspect recurring-materialization coupling that makes assignment-start backdating unsafe:
  - `sed -n '360,470p' packages/billing/src/actions/contractCadenceServicePeriodMaterialization.ts`
  - `sed -n '380,430p' packages/billing/src/actions/clientCadenceScheduleRegeneration.ts`

## Links / References

- Existing stub plan folder: `ee/docs/plans/2026-03-21-client-default-contract-on-demand-routing`
- Related ongoing plan: `ee/docs/plans/2026-03-21-service-catalog-billing-mode-decoupling`
- Key current code surfaces identified by investigation:
  - `shared/billingClients/billingSettings.ts`
  - `shared/billingClients/billingSchedule.ts`
  - `packages/billing/src/actions/billingCycleAnchorActions.ts`
  - `packages/billing/src/actions/billingSettingsActions.ts`
  - `packages/billing/src/actions/creditExpirationSettingsActions.ts`
  - `packages/scheduling/src/lib/contractLineDisambiguation.ts`
  - `packages/billing/src/lib/contractLineDisambiguation.ts`
  - `packages/billing/src/lib/billing/billingEngine.ts`
  - `packages/billing/src/actions/billingAndTax.ts`
  - `packages/billing/src/actions/invoiceGeneration.ts`
  - `packages/billing/src/components/billing-dashboard/AutomaticInvoices.tsx`
  - `packages/scheduling/src/components/time-management/time-entry/time-sheet/ContractInfoBanner.tsx`
  - `packages/clients/src/actions/clientActions.ts`
- New/updated implementation files:
  - `shared/billingClients/defaultContract.ts`
  - `shared/billingClients/billingSettings.ts`
  - `shared/billingClients/billingSchedule.ts`
  - `shared/billingClients/createBillingCycles.ts`
  - `packages/billing/src/actions/billingCycleAnchorActions.ts`
  - `packages/billing/src/actions/billingCycleActions.ts`
  - `packages/billing/src/actions/billingScheduleActions.ts`
  - `packages/billing/src/actions/billingSettingsActions.ts`
  - `packages/billing/src/actions/creditExpirationSettingsActions.ts`
  - `packages/clients/src/components/clients/ClientBillingSchedule.tsx`
  - `server/migrations/20260321150000_add_system_managed_default_contract_marker.cjs`
  - `shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
  - `packages/clients/src/actions/clientActions.ts`
  - `shared/models/clientModel.ts`
  - `server/src/lib/api/services/ClientService.ts`
  - `packages/integrations/src/services/xeroCsvClientSyncService.ts`
  - `shared/services/emailService.ts`
  - `ee/docs/plans/2026-03-21-system-managed-default-contract-cutover/ENGINEERING_NOTES.md`

## Completed Checklist Progress

- (2026-03-21) Completed features: `F001-F018`, `F055`, `F056`, `F063`, `F068`.
- (2026-03-21) Completed tests: `T001`, `T002`.

## Open Questions

- Should default-contract pointer be persisted in billing settings or inferred by deterministic query?
- Should API base delete always delegate to domain delete orchestration for client entity type?
- What is final policy when billing settings are explicitly set to null/default state: keep default contract dormant or remove assignment?
- Should the optional historical bootstrap date be persisted in `client_billing_settings` as durable metadata, or used as operational input that only shapes generated `client_billing_cycles`?
- What exact pricing source should unmatched default-contract work use once the default contract no longer authors recurring lines?

## Progress Update (2026-03-21)

- Resolver/date cutover: both scheduling and billing `contractLineDisambiguation` now accept `effectiveDate` and apply date-window filtering using `start_date <= effectiveDate(end-of-day)` and `end_date is null || end_date >= effectiveDate(start-of-day)`.
- Save/UI callers now pass effective dates consistently: time-entry save uses computed `work_date`, usage save/update uses `usage_date`, and UI eligible-lines queries pass entry/usage date.
- Removed display-only ambiguous default selection in `ContractInfoBanner`; ambiguous multi-line matches now require explicit selection instead of showing a synthetic default.
- Billing engine unresolved reconciliation now persists deterministic single eligible contract-line assignments for time/usage with `whereNull(contract_line_id)` guards, then excludes those records from unresolved output.
- Recurring due-work now emits primary unresolved identity keys (`schedule:*:unresolved:*`) instead of legacy `non_contract` keys; invoice-generation and UI parsing now support both unresolved and legacy non-contract formats for backward compatibility.
- Completed features: `F019-F026`.
- Completed tests: `T003`, `T004`.
- Completed features: `F027-F033`.
- Completed tests: `T005`, `T006`, `T007`.
- Completed features: `F034-F037`.
- Completed tests: `T008`.

## Additional Runbooks (2026-03-21)

- Verify T003/T004 effective-date coverage:
  - `cd packages/scheduling && npx vitest run tests/timeEntryCrud.changeRequests.test.ts`
  - `cd server && npx vitest run ../packages/billing/tests/usageActions.effectiveDate.test.ts`
- Verify reconciliation behavior for deterministic vs ambiguous unresolved work:
  - `cd server && npx vitest run src/test/unit/billing/billingEngine.unresolvedReconciliation.test.ts`
- Verify unresolved-key candidate + generation compatibility:
  - `cd server && npx vitest run src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts src/test/unit/billing/nonContractDueWork.integration.test.ts src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx`
- Re-run default-contract ensure suite after fallback hook expansion:
  - `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
- Typecheck touched shared/integration workspaces:
  - `npm -w shared run typecheck`
  - `npm -w @alga-psa/integrations run typecheck`
  - `npm -w @alga-psa/scheduling run typecheck` (currently fails due pre-existing `packages/clients` type errors unrelated to this plan)

## Progress Update (2026-03-21, F038/F039/T009)

- Added explicit recurring due-work attribution metadata on row/candidate shapes (`source`, business label, completeness, missing fields) to carry grouped-row assignment context through server and UI layers.
- `billingAndTax` now stamps persisted rows as `explicit_contract` vs `system_managed_default_contract` and unresolved rows as `unresolved`; grouped candidates aggregate attribution summaries.
- Persisted rows with incomplete contract attribution metadata are now marked non-generatable with a blocking reason before they reach grouped selection.
- `AutomaticInvoices` now consumes attribution metadata for grouped-row context labels and warning copy (`Assignment attribution metadata missing ...`) instead of relying on heuristic-only contract field checks.
- Added UI guard coverage for grouped rows: business-safe labels for system-managed default and unresolved work, plus hard-block behavior for metadata-missing rows.
- Completed features: `F038`, `F039`.
- Completed test: `T009`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx`
- `cd server && npx vitest run src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts src/test/unit/billing/nonContractDueWork.integration.test.ts`
- `npm -w shared run typecheck`

### Notes

- `npm -w @alga-psa/billing run typecheck` still reports unrelated pre-existing workspace errors outside this change set; new attribution changes compile within exercised paths.
- Running `automaticInvoices.recurringDueWork.ui.test.tsx` in the same invocation currently triggers existing router-mount test harness issues (`invariant expected app router to be mounted`) not introduced by this work.

## Progress Update (2026-03-21, F040-F044/T010)

- Updated contract list UI (`ClientContractsTab`) to surface `System-managed default` badge and helper copy (`Created automatically for uncontracted work`) directly in contract-name cells.
- Added system-managed lifecycle guardrails in list actions: default contracts now only expose view/details access and hide destructive/manual lifecycle operations (`Delete`, `Terminate`, `Restore`, `Set to Active`).
- Updated contract detail UI (`ContractDetail`) with explicit system-managed banner/copy and read-only behavior for lifecycle/ownership-sensitive controls.
- Detail view now disables ownership-changing controls (assignment edit, lifecycle selectors, save) and hides destructive delete action for system-managed default contracts.
- Added static UI contract test coverage for list/detail guardrails and copy semantics.
- Completed features: `F040`, `F041`, `F042`, `F043`, `F044`.
- Completed test: `T010`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx src/test/unit/billing/systemManagedDefaultContracts.ui.static.test.ts`
- `cd server && npx vitest run src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts src/test/unit/billing/nonContractDueWork.integration.test.ts`

### Notes

- `T010` is currently implemented as a static UI contract test due test-environment import-resolution issues when rendering full `ContractDetail` runtime dependencies in isolation.

## Progress Update (2026-03-21, F045/F046/T011)

- Updated time-entry contract banner copy to remove `default rates` fallback language and use explicit `system-managed default contract` terminology for unmatched service lines.
- Updated fallback contract display label to `System-managed default contract` while preserving ambiguous-state messaging that requires explicit selection before persistence.
- Updated usage tracking tooltip, placeholder, and helper copy to mirror the same system-managed default terminology when client context is missing.
- Added a static UI terminology contract test covering both time-entry banner and usage tracking copy semantics, including guard text ensuring unresolved assignment remains explicit.
- Completed features: `F045`, `F046`.
- Completed test: `T011`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/defaultContractTerminology.ui.static.test.ts`

### Notes

- `T011` is currently implemented as a static source-contract test to avoid full UI runtime harness complexity while still enforcing copy semantics and unresolved-assignment wording.

## Progress Update (2026-03-21, F047/F048)

- Reworked `AutomaticInvoices` fallback assignment-context labels to business-safe copy, replacing technical identifier leaks in grouped rows:
  - `Assignment line <id>` -> `Assigned contract line`
  - `Execution <identity>` -> `Assigned work item`
- Preserved attribution-first behavior (`member.attribution.label`) so explicit/default/unresolved labels continue to display when provided by due-work attribution metadata.
- Added regression coverage in `automaticInvoices.nonContractSelection.ui.test.tsx` to ensure mixed explicit-contract + system-managed-default rows remain combinable when billing scopes align, and still generate as a single grouped parent target.
- Completed features: `F047`, `F048`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx`

### Notes

- Broader legacy wiring suites still contain pre-existing brittle string expectations unrelated to this feature; feature verification was scoped to the recurring automatic-invoices UI integration test that exercises the changed behavior.

## Progress Update (2026-03-21, F049/F050)

- Added action-layer billing permission gates in `contractActions` for contract-view and mutation entry points used by billing contract list/detail flows (`read`, `create`, `update`).
- Added explicit server-side mutation guardrails to block create/update payload attempts that include system-managed identity fields (`is_system_managed_default`, `owner_client_id`).
- Sanitized create/update payload stripping for protected fields to ensure no accidental pass-through into model writes.
- Added wiring coverage asserting these guardrails stay present in contract actions.
- Completed features: `F049`, `F050`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx src/test/unit/billing/systemManagedContractGuardrails.wiring.test.ts`

### Notes

- Guardrails are implemented at action entry points so API/controller paths that call these actions inherit the same permission and mutation protections.

## Progress Update (2026-03-21, F051-F054)

- Added structured ensure observability in `shared/billingClients/defaultContract.ts`:
  - `default_contract.ensure` events for `created`, `reused`, and `skipped_no_billing_configuration` outcomes.
  - Included metric markers: `default_contract_created`, `default_contract_reused`, and skip marker.
- Added structured resolver routing logs in both scheduling and billing disambiguation libs:
  - `contract_line_resolver.routing` events with decisions `explicit`, `default`, or `ambiguous_or_unresolved`.
  - Included ambiguous marker metric `unresolved_ambiguous_count`.
- Added billing-engine reconciliation observability for unresolved write-back flow:
  - `billing_engine.reconcile.unresolved` events for deterministic single-match persistence and ambiguous/no-match skips.
  - Included deterministic marker `unmatched_resolved_deterministically` and ambiguous marker `unresolved_ambiguous_count`.
- Added wiring tests to lock observability contract points for ensure, resolver, and reconciliation paths.
- Completed features: `F051`, `F052`, `F053`, `F054`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/defaultContractObservability.wiring.test.ts src/test/unit/billing/systemManagedContractGuardrails.wiring.test.ts src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx`

### Notes

- Structured payloads intentionally avoid end-user fields beyond tenant/client/record identifiers already present in server action context.

## Progress Update (2026-03-21, F057/F058)

- Validated and locked lazy backfill behavior via wiring coverage:
  - `ensureDefaultContractForClientIfBillingConfigured` gates ensure on `client_billing_settings` existence and returns `{ ensured: false }` otherwise.
  - This preserves no-forced-global-backfill behavior and first-qualifying-touchpoint creation semantics.
- Validated and locked targeted reconciliation wiring:
  - Due-work unresolved collection routes through `BillingEngine.calculateUnresolvedNonContractChargesForExecutionWindow`, which performs deterministic single-match write-back while leaving ambiguous/no-match rows unresolved.
- Added a dedicated wiring test file for lazy-backfill + reconciliation path contracts.
- Completed features: `F057`, `F058`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/defaultContractLazyBackfill.wiring.test.ts src/test/unit/billing/defaultContractObservability.wiring.test.ts`

## Progress Update (2026-03-21, F059)

- Added explicit sequencing runbook at `SEQUENCING_RUNBOOK.md` with stage gates, required-state criteria, and verification commands.
- Sequencing now formalizes cutover dependencies across:
  - data model + ensure,
  - hook coverage,
  - resolver/date alignment,
  - reconciliation semantics,
  - invoice selection/attribution safeguards,
  - UI guardrails,
  - lifecycle cleanup parity,
  - observability checks.
- Included rollback/safety rules to avoid partial-cutover invalid states and premature fallback removal.
- Completed feature: `F059`.

## Progress Update (2026-03-21, F061)

- Added `DEVELOPER_RUNBOOK.md` covering default-contract lifecycle, routing, reconciliation, grouped-attribution behavior, and operational verification commands.
- Documented forward guardrails to prevent reintroducing eager creation or identity-field bypasses.
- Completed feature: `F061`.

## Progress Update (2026-03-21, F069)

- Enforced canonical system-managed default contract naming convention during ensure:
  - existing default-contract rows are normalized to
    - name: `System-managed default contract`
    - description: `Created automatically for uncontracted work`
  - normalization occurs on ensure touchpoints without creating duplicate contracts.
- Added shared ensure regression coverage for legacy-named default contracts to guarantee canonical rename + assignment ensure behavior.
- Completed feature: `F069`.

### Verification commands

- `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`

## Progress Update (2026-03-21, F060/F066/F067)

- Removed obsolete legacy branch filtering in recurring invoice selection scoping:
  - dropped dead `__non_contract__` obligation-prefix exclusion in invoice generation,
  - retained legacy key parsing only at the schedule-key parser for backward compatibility.
- Renamed internal selector helper in invoice generation from non-contract-centric wording to unresolved-centric wording to match cutover semantics.
- Audited integration-created client pathway (`xeroCsvClientSyncService`) and confirmed first billing-config touchpoint hook still calls shared default-contract ensure.
- Added/kept wiring coverage asserting package/shared billing settings + schedule/anchor paths continue to use shared ensure primitives, preventing cross-package drift.
- Completed features: `F060`, `F066`, `F067`.

### Verification commands

- `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
- `cd server && npx vitest run src/test/unit/billing/defaultContractCrossPackageParity.wiring.test.ts src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts`

## Progress Update (2026-03-21, F062)

- Updated API contract schema to expose default-contract metadata explicitly:
  - added `is_system_managed_default` to `contractResponseSchema`.
- Added schema unit coverage verifying:
  - response payloads accept and expose `is_system_managed_default`,
  - create/update schemas keep system-managed identity marker out of writable request payloads.
- Completed feature: `F062`.

### Verification commands

- `cd server && npx vitest run src/test/unit/api/contractSchema.systemManagedDefault.schema.test.ts`

## Progress Update (2026-03-21, F064/F065/F070)

- Added a shared deterministic selection helper in both billing and scheduling disambiguation modules:
  - `resolveDeterministicContractLineSelection` now makes precedence explicit,
  - single explicit eligible line wins,
  - system-managed default (bucket-overlay line) is used only as fallback when it is uniquely deterministic,
  - ambiguous multi-active scenarios remain unresolved.
- Added package-level resolver tests in both billing and scheduling to lock fallback precedence and ambiguity behavior.
- Improved recurring invoice history attribution context:
  - history row mapping now computes explicit vs system-managed-default assignment sets from invoice charge assignments,
  - added stable history metadata fields (`assignmentDefaultContractIds`, `assignmentExplicitContractIds`, `assignmentSourceSummary`),
  - replaced raw-ID assignment labels with business-safe summaries (`System-managed default contract`, `Explicit contract assignment`, `Mixed assignment`).
- Added regression coverage for recurring invoice selection scoping to ensure contract-cadence execution windows remain explicit-obligation scoped and do not leak unresolved fallback selection semantics.
- Completed features: `F064`, `F065`, `F070`.

### Verification commands

- `npx vitest run --config vitest.config.ts tests/contractLineDisambiguation.defaultFallback.test.ts` (run in `packages/billing`)
- `npx vitest run --config vitest.config.ts tests/contractLineDisambiguation.defaultFallback.test.ts` (run in `packages/scheduling`)
- `cd server && npx vitest run src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts src/test/unit/billing/recurringInvoiceHistory.defaultContractAttribution.wiring.test.ts src/test/unit/api/contractSchema.systemManagedDefault.schema.test.ts`

## Progress Update (2026-03-21, T012-T018)

- Added lifecycle cleanup parity wiring tests for client delete flows:
  - `T012` package action path asserts deletion of billing settings/cycles and assignment artifacts.
  - `T013` API service path asserts cleanup orchestration includes default-contract assignment/header cleanup hooks.
- Extended shared billing-settings ensure tests for null-override behavior:
  - `T014` verifies deleting billing-settings override does not recreate default-contract artifacts.
- Added migration contract test for default-contract marker migration:
  - `T015` asserts table/column guards and idempotent index create/drop patterns.
- Added recurring selection regression for cadence safety:
  - `T016` verifies contract-cadence selection remains explicit-obligation scoped with unresolved fallback disabled.
- Extended observability wiring tests:
  - `T017` verifies structured logs avoid obvious PII fields in ensure/resolver/reconcile codepaths.
- Extended integration-import regression wiring coverage:
  - `T018` verifies integration-created client flow retains first qualifying billing-config ensure hook.

### Verification commands

- `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts`
- `cd server && npx vitest run src/test/unit/billing/defaultContractDeletionCleanup.wiring.test.ts src/test/unit/billing/defaultContractCrossPackageParity.wiring.test.ts src/test/unit/billing/defaultContractObservability.wiring.test.ts src/test/unit/migrations/systemManagedDefaultContractMarkerMigration.test.ts src/test/unit/billing/invoiceGeneration.unresolvedSelectionKeys.test.ts`

## Progress Update (2026-03-21, F071-F074/F085)

- Reclassified system-managed default contracts as attribution-only in runtime guardrails:
  - backend mutation paths now block authoring for default contracts across contract update, contract-line mapping/line/config mutations, pricing schedules, and client-contract assignment mutation paths.
- Removed system-managed default contracts from recurring cadence authority surfaces:
  - contract cadence and client cadence materialization queries now explicitly exclude `contracts.is_system_managed_default = true`.
  - recurring due-work persisted-row readers and client-cadence materialization-gap checks now exclude system-managed defaults.
  - recurring service-period admin schedule listing filters out system-managed defaults, and direct management view for legacy schedule keys now hard-blocks with attribution-only messaging.
- Updated contract UI to attribution-only semantics:
  - contract detail alert copy now explains attribution-only behavior and points users to normal user-authored contracts for custom billing behavior.
  - contract lines/pricing tabs are disabled on system-managed defaults; lines/pricing components run in read-only mode with explanatory copy.
  - contract list helper copy now includes attribution-only wording.
- Added/updated static wiring tests locking the above behavior:
  - `systemManagedDefaultAttributionShell.wiring.test.ts`
  - `systemManagedDefaultContracts.ui.static.test.ts`

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/systemManagedDefaultAttributionShell.wiring.test.ts src/test/unit/billing/systemManagedDefaultContracts.ui.static.test.ts src/test/unit/billing/systemManagedContractGuardrails.wiring.test.ts`
- `npm -w @alga-psa/billing run typecheck` *(fails with pre-existing workspace errors outside this change set; no new failing assertions in targeted tests)*

### Completed checklist progress

- Completed features: `F071`, `F072`, `F073`, `F074`, `F085`.

## Progress Update (2026-03-21, F075/F076)

- Updated billing engine runtime timing resolution so system-managed default contract lines always use client-schedule cadence windows:
  - `buildRecurringChargeTimingSelection` now forces `cadenceOwner = client` whenever `is_system_managed_default` is true.
  - prevents default-contract assignments from reintroducing contract-anniversary timing semantics.
- Added legacy-safety pricing guardrails for system-managed default line charges:
  - time-charge rating now skips contract-line service-config rounding/minimum/user-type overrides when line is system-managed default.
  - usage-charge rating now skips contract-line service-config minimum/custom/tiered overrides when line is system-managed default.
  - this keeps unmatched default-contract billing on default/service-catalog pricing semantics.
- Added wiring tests to lock client-schedule timing + pricing override bypass behavior.
- Completed features: `F075`, `F076`.

### Verification commands

- `cd server && npx vitest run src/test/unit/billing/defaultContractClientSchedulePricing.wiring.test.ts src/test/unit/billing/systemManagedDefaultAttributionShell.wiring.test.ts`

## Progress Update (2026-03-21, F077-F084/F086, T019-T024)

- Implemented optional historical billing bootstrap flow on client billing schedule save:
  - Added optional `billingHistoryStartDate` through shared schedule domain, package action, client helper, and client UI.
  - Added shared bootstrap preview contract with normalized boundary, uninvoiced regeneration count, and invoiced-history lock status.
- Added deterministic historical client-cycle regeneration/backfill behavior:
  - User-entered history date normalizes to containing cycle boundary.
  - Uninvoiced cycles from normalized boundary are rebuilt contiguously through current date.
  - Bootstrap requests earlier than earliest invoiced cycle boundary are blocked with explicit message.
- Converged manual effective-date bootstrap + schedule bootstrap boundary behavior in shared schedule helpers (`createNextBillingCycle` normalization).
- Completed attribution-shell and recurring-exclusion regression coverage:
  - Added UI wiring contract test for attribution-only list/detail semantics and disabled line/pricing/assignment edit surfaces.
  - Added wiring contract test for historical bootstrap + default-contract billing route semantics.
  - Added wiring contract test for recurring/service-period materialization and recurring admin exclusion of system-managed defaults.
- Updated plan docs/runbooks for attribution-shell model and historical bootstrap workflow/gates (`ENGINEERING_NOTES.md`, `DEVELOPER_RUNBOOK.md`, `SEQUENCING_RUNBOOK.md`).
- Completed features: `F077`, `F078`, `F079`, `F080`, `F081`, `F082`, `F083`, `F084`, `F086`.
- Completed tests: `T019`, `T020`, `T021`, `T022`, `T023`, `T024`.

### Verification commands

- `npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSchedule.historyBootstrap.test.ts`
- `cd server && npx vitest run src/test/unit/billing/ClientBillingSchedule.ui.test.tsx src/test/unit/billing/defaultContractClientSchedulePricing.wiring.test.ts src/test/unit/billing/systemManagedDefaultAttributionShell.wiring.test.ts src/test/unit/billing/systemManagedDefaultContracts.ui.static.test.ts src/test/unit/billing/defaultContractDeletionCleanup.wiring.test.ts src/test/unit/billing/systemManagedContractGuardrails.wiring.test.ts`
- `cd server && npx vitest run src/test/unit/billing/systemManagedDefaultAttributionOnly.ui.wiring.test.ts src/test/unit/billing/defaultContractHistoricalBootstrapAndBillingRoute.wiring.test.ts src/test/unit/billing/systemManagedDefaultRecurringExclusion.wiring.test.ts src/test/unit/billing/systemManagedDefaultAttributionShell.wiring.test.ts src/test/unit/billing/defaultContractClientSchedulePricing.wiring.test.ts src/test/unit/billing/systemManagedDefaultContracts.ui.static.test.ts`
