diff --git a/README.md b/README.md index 42f7e88..2e39c13 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,70 @@ -# domus -A comprehensive household management platform +# Domus — Intelligent Household Management + +**Your home. In harmony.** + +Domus is a local-first household application for Home Assistant, bringing tasks, +calendar planning, shopping, pantry inventory, family participation and automation +into one responsive interface. Normal operation does not require AI or cloud services. + +## Project status + +Domus is in the specification phase. No application is implemented or published yet. +The [documentation foundation issue](https://github.com/vypdev/domus/issues/2) +tracks eleven Draft SDDs, 82 normative requirements and 353 planned acceptance cases. +These cases are verification plans, not executed application tests. + +The first usable release covers all six domains, Supervisor App/Ingress and +standalone Container, and isolated Stable and experimental Edge channels. +Every participant uses their own Home Assistant account. The existing HA gateway +is already integrated; Domus supplies native entities and services and does not +implement another MCP server. + +The owner-selected stack is Python/FastAPI, SQLite and Lit/TypeScript/Vite, with +one household per installation and a thin HA integration. Domus owns HA-coherent +presentation components, a Storybook catalog and Playwright browser contracts. +Simple/default and optional advanced automation editors are both launch scope, +sharing one durable declarative engine. Collaborative points allocation is configurable +in the application, with the chosen policy and actual awards preserved in the ledger. + +## Read the foundation + +- [Product vision and confirmed owner requirements](docs/product-vision.md) +- [Architecture, boundaries and evaluated alternatives](docs/architecture.md) +- [Capability catalog and SDD index](specs/CATALOG.md) +- [Home Assistant entities and services](docs/contracts/home-assistant.md) +- [Open architectural and product decisions](docs/decisions.md) +- [Reference investigation](docs/reference-investigation.md) +- [Development milestones](docs/roadmap.md) +- [Acceptance, coverage and CI Check plan](docs/acceptance-plan.md) +- [Specification validation evidence and limitations](docs/sdd-validation.md) + +## Quality and contribution + +Clean Architecture is mandatory. Meaningful tests accompany every implementation +from its first change, with 100% supported first-party coverage metrics as the +required implementation gate. A future project-owned workflow named **CI Check** runs +the full applicable suite for every PR update. English is used for issues, +documentation, source identifiers and comments; the product supports English and Spanish. + +Google Chrome dogfooding is authorized against the owner's local Home Assistant, +using identifiable test data and explicit cleanup. Stable and Edge data, credentials +and HA identities stay separate. + +Read [the specification standard](specs/README.md) and the owning SDD before changing +a capability. Follow the existing [repository collaboration guide](.copilot/AGENT_GUIDE.md) +for Action-managed branches and linked PRs. Copilot's implementation and installed +resources remain unchanged; the owner's only narrow exception is project dependency +preparation when necessary. Merge, release and deployment remain separately authorized. + +## Readiness limitations + +All SDDs remain Draft while material decisions are reviewed. Their original Copilot +format and consistency checks pass. The proposed SDK catalog still fails the unchanged +upstream evidence validator because application entrypoints, source and tests do not +exist yet; no fake paths or gate-readiness claims are used. See the +[adoption note](docs/copilot-adoption.md). + +The supplied brief ends at the beginning of section 10.2. The owner completed the +barcode scope on 2026-10-29: camera/manual entry, local matching and optional Internet +product lookup. Provider feasibility and device evidence still require review. +No application build/test commands or CI workflow are installed by this documentation-only change. diff --git a/docs/acceptance-plan.md b/docs/acceptance-plan.md new file mode 100644 index 0000000..5eedde9 --- /dev/null +++ b/docs/acceptance-plan.md @@ -0,0 +1,47 @@ +# Verification and acceptance plan + +The SDD inventory contains 353 distinct planned cases across eleven capabilities. +The counts are derived from concrete observable scenarios and are minimums; no application tests have run. +Formatting, catalog metadata, branch readiness and working product acceptance are separate gates. + +## From the first source file + +Write meaningful behavior tests with each implementation. Enforce 100% supported first-party line, statement, +function and branch metrics separately for backend, frontend and integration code. +Do not mask untested paths with broad exclusions or count generated/third-party code as authored coverage. +Architectural rules, schema validation, permissions, replay/races and recovery are executable checks from the start. +Use deterministic clocks, IDs, bounded provider fakes and injected transaction failures. + +The 2026-10-29 owner decisions add concrete cases for role-default verification, Ingress/host-context boundaries, configurable points allocation and actual-total reversals, optional external product lookup, recurrence anchored to actual work with per-task successor timing, and one automation engine with both editors. Its 45-case floor covers schema/editor round trips, permissions, durable waits/replay, partial recovery, resource/loop budgets and target/channel isolation. Case IDs, per-area budgets and reverse requirement mappings are regenerated together before running the unchanged original Copilot consistency functions. + +The continued owner review specifies adjustable material quantities in the completion submission, stock shortfalls retained as pending consumption without negative stock, actual-work reporting periods, recurrence-edit previews and visible missed occurrences. Ledger cases additionally cover atomic performer allocations, closed completion cycles, already-spent-point reversals and negative-balance recovery. Receipt-retention and current-authorization cases prevent cleanup or replay from bypassing domain invariants. + +The latest owner decisions add prerequisite-review preservation, durable disablement fencing and approved-reward funding holds, including admission/fulfillment/reversal races and restart. Identity cases cover all three administrator mappings, current HA-source revocation, configurable household profiles, member-override precedence and last-administrator safety. Repeated-time cases cover the first/second appearance and one-execution identity; UI/HA cases exercise the same policies without trusting a role label, transport credential or host hint as authority. + +## CI Check contract + +A project-owned workflow named CI Check runs for opened, reopened, synchronized and ready-for-review PR heads; +draft PRs still run tests. Do not use path filters to skip suites. Merge-queue validation is included if enabled. +Run backend/domain, frontend, HA contract/integration, migration/security, architecture, docs, localization, +browser E2E and both-target/channel packaging suites. The aggregate cannot pass if a required job is missing, +unexpectedly skipped, failed or cancelled. Record the exact checked revision and coverage reports. + +PR code runs without publication credentials. Persistent self-hosted runner execution requires the repository's +trusted-PR policy; a skipped untrusted-fork run is not passing evidence. Provision toolchains in the job +that executes tests. The existing Copilot files remain unchanged. + +## Real environment evidence + +Use disposable HA for automated integration tests. Use the owner's Google Chrome/local HA authorization +for controlled dogfooding of the implemented experimental artifact, across all domain workflows, +mobile/narrow layouts, themes, keyboard and screen-reader order. Record artifact SHA/digest, target, +channel, test data IDs, outcomes and cleanup. Screenshots supplement written semantic results; +browser success does not replace test coverage. + +## First integrated release gates + +Both deployment targets and Stable/Edge isolation pass the same business fixtures. +Cross-domain maintenance/material/receipt/points scenarios reconcile ledger totals and visible states. +Failure and compensation paths remain understandable. Documentation and actual schemas agree. +Every material decision is resolved before the owning SDD becomes Ready for implementation. +No release, production install or promotion is authorized by this package. diff --git a/docs/adr/0001-application-boundary.md b/docs/adr/0001-application-boundary.md new file mode 100644 index 0000000..7e85bbc --- /dev/null +++ b/docs/adr/0001-application-boundary.md @@ -0,0 +1,23 @@ +# ADR 0001 — Modular application with a thin HA companion + +- Status: Accepted by owner on 2026-10-29; implementation verification pending +- Date: 2026-10-28 +- Decision owners: Domus product and architecture reviewers + +## Context + +Both Supervisor App/Ingress and standalone Container are confirmed launch targets. +Domus needs its own complete UI and durable household business model. + +## Decision + +Use one modular local server and a thin native HA companion integration. +Domain and application code depend on ports; frameworks and SQL remain adapters. +The owner selected Python/FastAPI, SQLite and Lit/TypeScript/Vite on 2026-10-29, with one household per installation. Domus owns HA-coherent presentation components, Storybook fixtures and Playwright browser tests. Exact dependency versions, authentication, storage concurrency and the supported HA/browser matrix still require engineering evidence; this decision does not declare any implementation complete. + +## Alternatives and consequences + +A custom integration alone shares too much complex runtime work with HA Core. +An App alone excludes standalone and native entity registration. +The hybrid adds packaging/identity work but gives both targets the same business core. +The gateway remains unchanged. No MCP is introduced. diff --git a/docs/adr/0002-authoritative-records.md b/docs/adr/0002-authoritative-records.md new file mode 100644 index 0000000..b33bf16 --- /dev/null +++ b/docs/adr/0002-authoritative-records.md @@ -0,0 +1,21 @@ +# ADR 0002 — Domus owns domain facts and immutable ledgers + +- Status: Proposed +- Date: 2026-10-28 +- Decision owners: Domain and data reviewers + +## Context + +Tasks need occurrences and history; purchases need physical receipt; stock and points need correction/replay integrity. + +## Decision + +Propose Domus as authority for its records, with separate definition/occurrence and purchase/receipt facts, +immutable stock and points ledgers, operation receipts and transactional outbox/inbox boundaries. +HA views are projections. Unrelated native HA lists are not competing stores. + +## Alternatives and consequences + +A mutable stock/points integer loses auditability. Bidirectional uncontrolled mirroring creates ownership conflicts. +Ledgers add projection and compensation work, but make retries, reopening and restores explainable. +This does not require rebuilding every business record from events or introducing a distributed broker. diff --git a/docs/adr/0003-ha-public-surface.md b/docs/adr/0003-ha-public-surface.md new file mode 100644 index 0000000..e56d59e --- /dev/null +++ b/docs/adr/0003-ha-public-surface.md @@ -0,0 +1,21 @@ +# ADR 0003 — Native HA entities and services, no new MCP + +- Status: Proposed +- Date: 2026-10-28 +- Decision owners: Integration and security reviewers + +## Context + +The owner confirms the existing gateway is already integrated and will consume Domus capabilities through HA. + +## Decision + +Expose bounded native entities, response services and events. Use stable registry IDs and instance/channel selection. +Route mutations through the same domain use cases as the UI. Verify individual HA identity or use narrow technical grants. +Rich queries use structured responses, not unbounded entity attributes. + +## Alternatives and consequences + +A second MCP duplicates the owner's ecosystem and is excluded. +An unrestricted backend proxy bypasses semantic contracts and is rejected. +A native surface needs HA version/identity tests but gives UI, automations and existing MCP a shared product contract. diff --git a/docs/adr/0004-quality-and-channels.md b/docs/adr/0004-quality-and-channels.md new file mode 100644 index 0000000..293fe4d --- /dev/null +++ b/docs/adr/0004-quality-and-channels.md @@ -0,0 +1,21 @@ +# ADR 0004 — Tests from the first implementation and isolated channels + +- Status: Proposed implementation; owner requirements confirmed +- Date: 2026-10-28 +- Decision owners: Quality and release reviewers + +## Context + +The owner requires Clean Architecture, maximum test coverage, Stable/experimental channels and CI Check on each PR update. + +## Decision + +Enforce 100% supported first-party coverage metrics with meaningful behavior assertions and architecture checks. +Use a new project-owned CI Check workflow and separate Stable/Edge credentials, storage and HA identities in both targets. +Use immutable source/image evidence and controlled Chrome dogfooding at the authorized local HA. + +## Alternatives and consequences + +Copying the gateway's lower coverage threshold would violate the new requirement. +A shared Stable/Edge DB would make experiments production mutations and is rejected. +More fixtures and packaging checks are required. Copilot remains unchanged; release remains explicitly authorized. diff --git a/docs/adr/0005-one-automation-engine.md b/docs/adr/0005-one-automation-engine.md new file mode 100644 index 0000000..ff9b690 --- /dev/null +++ b/docs/adr/0005-one-automation-engine.md @@ -0,0 +1,23 @@ +# ADR 0005 — One declarative automation engine with two editing levels + +- Status: Accepted product direction by owner on 2026-10-29; detailed engine contracts remain Draft +- Date: 2026-10-29 +- Decision owners: Domus product, architecture and security reviewers + +## Context + +The owner wants simple in-application rules by default and a complete optional advanced mode, both in the first release. HA must also consume Domus capabilities through native entities and services without gateway changes. + +## Decision + +Use one versioned declarative model and durable engine behind simple and advanced editors. The advanced editor adds bounded branching, repetition/parallelism, waits, simulation and inspectable traces. Both call the same authorized domain use cases; the HA adapter delegates to the engine where a stored rule is invoked. + +Keep domain invariants in their owning modules. Run receipts, pinned rule revisions, durable waits, current permission checks and causal budgets define replay, edits, cancellation and partial recovery. The simple form preserves unsupported advanced fields and directs editing to advanced mode. + +The owner confirmed disablement semantics on 2026-10-29: stop new runs and subsequent steps, let an already-started atomic command finish and preserve its actual effects. Durable control revisions fence queued/waiting and parallel work; restart or re-enable cannot silently resume cancelled runs. Numeric limits and the implementation of those guarantees still require evidence. + +## Consequences and alternatives + +Two unrelated rule engines would duplicate behavior and complicate recovery, so they are rejected. Arbitrary scripts and raw backend/network passthrough are outside this declarative contract. More combinations require meaningful schema, race, replay, loop, browser and recovery tests from first implementation. Numeric limits, action catalog and supported-version proof remain engineering gates before Ready for implementation. + +Both modes are launch scope; this ADR does not authorize runtime implementation, merge or deployment. Copilot and the gateway remain unchanged. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..8c6a6f5 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,112 @@ +# Proposed Domus architecture + +Status: Core architecture and stack accepted by the owner on 2026-10-29; implementation-specific decisions and evidence remain pending in [decisions](decisions.md). +Clean Architecture is a fixed owner requirement, not an optional style. + +## Delivery alternatives + +| Alternative | Benefits | Costs / limits | Assessment | +|---|---|---|---| +| Custom integration and custom panel only | One HA installation surface; direct native entities | Complex business persistence/UI jobs share Core lifecycle; no independent server boundary | Rejected as primary architecture | +| Supervisor App only | Own server, DB and Ingress UI | Does not cover confirmed standalone Container target; App alone is not a native entity provider | Insufficient | +| Independent server only | Full UI and deployment flexibility | Native entities/services still require a thin integration; standalone identity must be designed | Useful core, incomplete HA surface | +| Modular server plus companion integration | Same local core in App and Container; thin native HA adapter; independent UI | Two packages and explicit installation credential; more acceptance fixtures | Accepted by owner 2026-10-29 | + +The owner requires both deployment targets from the first usable release. +The companion integration is Domus's native HA surface. The already integrated gateway remains unchanged. + +## Components and dependency direction + +```mermaid +flowchart LR + Browser[English/Spanish UI] --> HTTP[HTTP adapter] + HA[Domus HA integration] --> API[Scoped domain API adapter] + HTTP --> App[Application commands and queries] + API --> App + App --> Domain[Pure domain policies] + App --> Ports[Semantic ports] + SQL[SQLite adapters] --> Ports + HAAdapters[HA transport adapters] --> Ports + App --> Outbox[Durable event outbox] + Outbox --> Projections[Read projections and HA notifications] +``` + +Text equivalent: UI and native HA adapters enter the same application use cases. Use cases depend inward +on pure domain and semantic ports. SQL, HTTP and HA transport implement those ports at composition time. +A durable outbox updates derived views without duplicating domain mutations. + +| Boundary | Owns | Enforced restriction | +|---|---|---| +| Domain | Value objects, entities, transitions, allocation and quantity policies | No frameworks, I/O, clock globals or concrete repositories | +| Application | Authorization, unit-of-work orchestration, commands, queries, ports | No SQL/HTTP/HA DTOs or concrete adapters | +| Infrastructure | DB, migrations, HA clients, bounded I/O, secret storage | No independent business rules | +| Entrypoints | Authentication, schema validation, safe mappings | No direct state/ledger manipulation | +| Frontend application | Controllers and transport-independent contracts | No browser fetch in domain decisions | +| Presentation | Components, navigation, view models and localized content | No role decisions or quantity/point calculation | +| Composition | Exactly one deployment wiring profile | No silent mode fallback | + +Architecture tests parse imports and module graphs, detect cycles, and exercise semantic contracts across adapters. +Directory names will follow these boundaries, but no fake source files are created in this documentation task. + +## Selected stack and trade-offs + +The owner selected Python/FastAPI, SQLite and Lit/TypeScript/Vite on 2026-10-29 after reviewing Gateway and Symphonia. Domus owns HA-coherent presentation components, a Storybook catalog and Playwright browser contracts. Components contain presentation behavior; API clients, authorization and domain orchestration remain outside them. Neither gateway code nor private HA bundles become runtime dependencies. +React was an evaluated alternative and is not the selected UI stack. A later change needs explicit evidence and a superseding decision. +One household per installation is confirmed. A single DB writer remains the initial concurrency proposal; a port-based storage seam permits a reviewed later database migration. +There is no broker, microservice mesh, cloud backend, event-sourced reconstruction requirement or MCP server. + +## One automation engine, two editors + +The owner confirmed a simple/default editor and optional advanced editor in the first release. Both edit one versioned declarative rule model, recorded in [ADR 0005](adr/0005-one-automation-engine.md). The [automation SDD](../specs/household-automation.md) owns typed triggers/conditions, bounded branching/repetition/parallel steps, durable waits, previews and execution traces. The HA integration maps native rule entrypoints to the same engine; it does not evaluate a second rule language. + +Rules invoke authorized domain commands and cannot replace stock, points or recurrence policy. A run pins rule revision and command receipts, checks current grants before each side effect and resumes only eligible durable waits after restart. Disabling prevents new runs and later steps while an already-started atomic command finishes with its real result retained. Durable control revisions fence old workers, queues and waits; re-enable does not silently restart cancelled work. Changing editor cannot discard unsupported advanced fields. Resource bounds, fencing and external-effect proof remain engineering gates; no arbitrary scripting or raw SQL/network proxy is introduced. + +The UI follows the owner's selected Symphonia/Gateway direction without inheriting assumptions about iframe context. Only a validated public host contract may supply UI hints; messages never establish identity or permissions. Theme and locale fall back deterministically to member/browser preferences when HA exposes no tested public signal. Domus does not inspect parent DOM or private storage. Host-managed safe-area padding applies once, and non-root Ingress paths need reload/deep-link tests as well as asset resolution. Storybook fixtures and Playwright scenarios enforce these boundaries. + +## Data consistency + +Definitions and occurrences, product identity and presentation, demand and purchase, receipt and stock posting, +and planned/actual actors are separate facts. Immutable stock and points ledgers use compensations. +Points use exact signed minor units and snapshot the configured allocation policy. Conservation of the base task value applies only to the conserve_total policy; other owner-required rounding/full-award policies record their actual total explicitly. Reopening compensates those actual entries rather than assuming the base value equals the award sum. +An allocation is unique per completion cycle independently of its policy version; all performer shares, inbox receipt and remainder-order change commit together. Closing a cycle prevents delayed approval or completion delivery from awarding it again. A genuine later completion has a separate cycle identity. Reversing spent points preserves any factual negative balance and fulfilled rewards while denying unaffordable new redemption. +Reopening a prerequisite retains already-completed dependent work, awards and material facts and adds a separate review condition, without cascading reopening. An approved unfulfilled reward that loses backing enters a funding hold with its approval/reservation retained. Reversal and fulfillment serialize against the same member funding state; authorized fulfillment requires sufficient backing and commits its debit with release of its reservation once. +The completion application orchestration accepts explicitly reviewed material intents in the same submission, delegating quantity rules to Inventory. Stable per-line identities preserve exact outcomes on replay. A stock shortage saves performed work plus a pending-regularization intent without a fabricated movement; explicit authorized settlement is separate from future restocking. Reopening a task never proves a physical material return. +Commands validate the authenticated principal, expected aggregate revision and idempotency key. +Receipt lookup/replay also checks current permissions. Routine audit retention cannot remove side-effect replay protection; compact guards and lifecycle identities remain consistent with backed-up business state. +A transaction commits domain state, operation receipt, audit reference and outbox. +Duplicate same-key requests return the original result; changed-payload replays return conflict. +Consumers record inbox identities with their effects. If a projection fails, the committed business operation +is reported as saved with pending follow-up. One UI green check cannot claim all side effects finished. + +## Deployment and identity + +Supervisor mode uses App/Ingress packaging and persistent App storage. Standalone uses a private Container +binding, an owned data volume, Core APIs and authenticated access; it assumes no Supervisor or Ingress. +Both map verified individual HA users to Domus membership and roles. Ingress headers are accepted only +behind a verified trust boundary; standalone never trusts a browser-supplied identity header. +HA OAuth or an equivalent supported HA authentication flow is a required proof step before implementation readiness. +No child PIN, shared adult session or parallel Domus password store is proposed. + +Administrator mapping is configurable. all_ha_administrators is the owner-selected default; setup_administrator and selected_ha_user are alternatives. The identity adapter must prove current HA identity/administrator status and retain inherited-grant provenance. Technical credentials never establish a human administrator. Explicit setup and authenticated recovery cannot promote a browser merely because it connected first; mapping changes cannot remove the last active effective administrator through a Domus command. External HA revocation still removes invalid inherited access. + +Predefined role profiles allow household grant adjustments and per-member exceptions. Effective authorization is a pure policy over trusted principal, current profile/member revisions, scope and hard domain constraints, with explicit member exceptions above configurable role defaults. Adapters do not apply alternate permission logic. Cached grants cannot survive a known revocation, and changing grants does not change a restricted performer's verification classification. + +Stable and Edge have separate instance IDs, HA registry unique IDs, credentials, DB volumes and exposed bindings. +The first release tests coexistence. An Edge installation cannot mutate Stable by accidentally selecting a +production entity; service commands validate installation/channel selection before applying a mutation. + +## Calendar and optional integrations + +Fixed schedules preserve anchors and retain missed occurrences visibly by default, with a per-task policy and explicit skip. Completion-relative rules anchor to actual completed_at independently of later verified_at. UTC instants and local +date-only values remain different types. The owner-confirmed DST gap policy advances an occurrence to the first valid local instant at or after its intended time while retaining nominal identity and showing the adjustment. Repeated local times resolve once to their first appearance by default, with a household second-appearance option and snapshotted policy. This is an explicit Domus policy, not unqualified RFC 5545 expansion semantics; interoperability still requires proof. +External calendar sync is optional future work: start with read-only export; any two-way sync would need +stable external UIDs, remote revision/ETag conflict detection, an explicit field owner, deletion tombstones, +loop prevention and a user-visible conflict queue. No local change is silently overwritten and no export is on by default. + +## Quality and operations + +Every implemented source file starts with tests; supported first-party coverage metrics target and enforce 100%. +CI Check covers backend, frontend, integration, contracts, architecture, browser UX and packaging for each PR update. +A backup includes schema, ledgers, receipts and media metadata. Restore verifies integrity and channel. +Rollback uses compatible application/data versions. Required real Google Chrome evidence supplements CI +at the owner's authorized local HA; test artifacts are identified and cleaned explicitly. diff --git a/docs/contracts/home-assistant.md b/docs/contracts/home-assistant.md new file mode 100644 index 0000000..d06a0d6 --- /dev/null +++ b/docs/contracts/home-assistant.md @@ -0,0 +1,169 @@ +# Proposed Home Assistant entity and service contract + +Status: Draft. Public identifiers below are proposals to review before implementation. +The existing Home Assistant gateway is already integrated. No gateway installation, code change, +MCP transport or MCP tool implementation belongs to this contract. + +## Source of truth and identity + +Domus owns its task, shopping, stock and points records. HA entities are derived views. +Existing unrelated native task/shopping lists remain untouched; future import would need its own reviewed policy. +Each installation/channel has a stable instance ID. Entity unique IDs include that ID and record identity, +so renaming an entity or co-installing Edge cannot alias Stable. +Services are registered once in HA under domus; selectors require a configured integration entry/instance, +and multi-instance calls must explicitly choose it. Names are stable English identifiers in every UI locale. + +## Entities + +| Proposed entity | State / semantics | Attributes or retrieval | +|---|---|---| +| sensor.domus_tasks_due | Count of pending due occurrences in household local day | freshness and bounded summary; detailed items via query_tasks | +| sensor.domus_tasks_overdue | Count of past-due incomplete occurrences | same count/filter semantics as UI | +| sensor.domus_low_stock_products | Count of active policies below threshold | query_inventory for details | +| `sensor.domus_member_points_` | Approved net earned points attributable to actual work in the current household week | stable member reference; excludes pending points; later approval updates the original work period | +| `sensor.domus_member_points_balance_` | Current posted ledger balance for one member, possibly negative after reversal | ledger query distinguishes balance, reserved and spendable quantities; not the weekly earned total | +| binary_sensor.domus_attention_required | Any authorized actionable household condition | bounded reason codes, never an unbounded record list | +| calendar.domus_schedule | Planned occurrence windows and due-date markers | stable UID; actual completion is not substituted | +| calendar.domus_completion_history | Optional separate actual-work timeline | completion UID and actual timestamp; explicit history label | +| todo.domus_tasks | Supported task occurrence projection with stable item UID | read plus only explicitly implemented native features | +| todo.domus_shopping | Outstanding purchasing intent | initially read-only; checkbox cannot silently mean receipt/stock posting | + +Actual entity_ids are assigned by HA and may have channel/instance suffixes; clients discover them. +Availability is unavailable when authoritative data cannot be read; empty successful collections remain empty success. +State properties read cached projection data and do not perform blocking network calls. + +## Services + +All services validate household/instance scope. Mutations accept an idempotency key and relevant expected revision. +Common responses are bounded and versioned. Query services return a response; native services only advertise features +whose semantics are supported. No arbitrary SQL, Python, URL proxy, shell or raw backend passthrough is exposed. + +| Proposed service | Purpose / important fields | Result | +|---|---|---| +| domus.query_tasks | filters, range, page_size, cursor | authorized occurrence summaries | +| domus.get_task | occurrence_id | definition snapshot, state, requirements, dependency-attention conditions and revision | +| domus.create_task | title and optional advanced policy | definition_id and occurrence_id | +| domus.update_task | definition_id or occurrence_id, expected_revision, explicit change | revised record; no historic rewrite | +| domus.assign_task | occurrence_id, assignee_ids | assignment revision and actual unchanged facts | +| domus.start_task | occurrence_id | state transition | +| domus.complete_task | occurrence_id, performer_ids, optional explicit material_lines with stable line IDs, actual quantities, units and storage targets | completion_id, verification/award status and per-line posted/pending-regularization material outcomes | +| domus.verify_task | completion_id, decision, reason | authorized verification result | +| domus.reopen_task | occurrence_id, reason | reopening and linked compensation status; completed dependents retain facts with review conditions | +| domus.skip_task | occurrence_id, reason | retained recurring exception | +| domus.reschedule_task | occurrence_id, explicit local date/instant | new planned window preserving original history | +| domus.pause_task_schedule | definition_id, paused | rule state without deleting existing work | +| domus.query_calendar | bounded range and filters | typed scheduled, due and completion entries | +| domus.query_inventory | product/location/low-stock filters, pagination | physical, reserved and available quantities | +| domus.record_stock_movement | product_id, location_id, amount, unit, movement_type, reason | immutable movement; corrections need privilege | +| domus.query_material_consumptions | completion_id or pending status, bounded filters and pagination | linked material intents, actual quantities and posted/pending outcomes | +| domus.resolve_material_consumption | intent_id, expected_revision, explicit settlement/correction/dismissal and reason | retained intent and validated movement when applicable; authorized, duplicate-safe resolution | +| domus.create_shopping_demand | list_id, product_id or free_text, quantity, unit, semantics | attributable demand_id | +| domus.query_shopping | list/status/source filters, pagination | consolidated lines with demand origins | +| domus.record_purchase | selected demands, purchased quantities, optional session/prices | purchase_id; no implied physical receipt | +| domus.receive_purchase | purchase_id, actual quantities and storage target | receipt_id and stock-posting status | +| domus.query_members | active/member filters | role-appropriate member summaries | +| domus.query_points | member/work-period/range/pagination | ledger entries, work-period totals, pending points, balance/reservations/spendable amount and scoped redemption funding/approval status with explicit timestamps | +| domus.query_automation_rules | rule/status filters, pagination | permission-filtered rule summaries and pinned revisions | +| domus.query_automation_runs | rule_id, state/range filters, pagination | bounded run and per-step outcomes | +| domus.preview_automation_rule | stored rule_id/revision and bounded sample input | pure explanation and proposed effects; no mutations | +| domus.trigger_automation_rule | rule_id, expected_revision, trigger identity and command key | durable run_id and admission result under the rule's grants | +| domus.set_automation_enabled | rule_id, enabled, expected_revision | authorized enable/disable; durable admission/step fence and settling-command status with retained effects | +| domus.get_operation | operation_id or own idempotency key | committed, pending, failed or unknown receipt | + +These cover initial HA consumer needs. The complete UI may use additional domain API operations; +no future service is claimed implemented by its appearance here. + +## Example command and response + +Illustrative request to complete a known occurrence; performer selection is a business target, +not the caller's identity: + +```json +{ + "instance_id": "example-edge-instance", + "occurrence_id": "example-occurrence", + "performer_ids": ["example-member"], + "material_lines": [ + { + "line_id": "example-material-line", + "product_id": "example-product", + "location_id": "example-location", + "quantity": "1", + "unit": "piece" + } + ], + "expected_revision": 7, + "idempotency_key": "example-completion-request" +} +``` + +Illustrative result: + +```json +{ + "contract_version": 1, + "status": "completed", + "operation_id": "example-operation", + "data": { + "occurrence_id": "example-occurrence", + "revision": 8, + "completion_id": "example-completion", + "verification_status": "pending", + "points_status": "not_awarded", + "material_results": [ + { + "line_id": "example-material-line", + "intent_id": "example-material-intent", + "status": "pending_regularization", + "reason_code": "insufficient_stock" + } + ] + }, + "pending": ["verification", "material_regularization", "home_assistant_projection"] +} +``` + +The occurrence result says the work was recorded, not that verification or rewards completed. +Material quantities are explicit actual usage, reviewed in the same submission by default or recorded separately according to the task setting. Per-line outcomes include posted, not_used for explicit zero usage, and pending_regularization. A pending_regularization intent is not a posted movement or negative stock, and its affected recorded quantity carries a discrepancy indicator. Later restocking alone does not settle it; an authorized reviewed action resolves the retained intent. Invalid or unauthorized material fields fail admission before new effects. Reopening or rejecting task verification does not fabricate a physical material return. Native to-do operations that cannot express required performer/material review are rejected with a supported UI/service path. +Points results expose base task points, the snapshotted allocation policy/version and precision, individual shares and actual total; rounded or full-performer policies may intentionally change the total. Ordinary completion callers cannot override that household/task policy. Completion data keeps actual completed_at distinct from verified_at so approval delay cannot move relative recurrence anchors. +Awards are unique per completion cycle independently of policy version, with all performer shares committed together. Reopening can leave a negative point balance when awards were already spent; new redemption remains blocked until affordability recovers, and fulfilled rewards remain fulfilled. +Reopening a prerequisite does not reopen completed dependents or reverse their awards. Task results retain completed state and expose dependency_attention with the prerequisite reference. An approved unfulfilled reward lacking backing enters funding_hold with approval/reservation retained; delivery remains blocked while unfunded, and recovery of credit does not assert physical delivery. Explicit authorized resolution is audited and cannot bypass affordability. +Work-period reporting uses actual completed_at in the household zone. A Sunday completion approved Monday contributes to Sunday's week only after approval; credit becomes available at ledger posting. verified_at and posted_at retain their actual timestamps. Linked reversals correct the original earned-work period without concealing when the correction occurred. Period earnings, pending points and spendable balance are separate response fields. +Statuses: completed, pending, invalid, denied, conflict, unavailable. +A successful empty query is completed with an empty items array, never unavailable. +Errors include a stable safe code, retryable flag, retained-state description and operation reference when known. +Examples are not live IDs or secrets. + +## Bounds and retry behavior + +Proposed defaults: 50 records per page, maximum 200; maximum response payload 256 KiB; +maximum 366-day calendar range. Cross-field validation rejects contradictory date forms and units. +Never silently truncate a record; return a cursor, a supported-limit error or a bounded unavailable result. +The final exact limits require acceptance review. + +An identical key/payload returns its stored result. Same key/different payload is conflict. +A transport timeout can leave outcome unknown; look up/replay the original key instead of using a new one. +Schemas reject unknown mutation fields. Mutating a stale revision never overwrites newer household work. + +## Authorization and automation + +A proven HA human context resolves the linked active member role. An automation or missing human context +uses only configured technical grants. A service field cannot assert that the caller is another person. +Administrator mapping defaults to all proven HA administrators and may instead select the verified setup administrator or an explicitly chosen HA user. Resolve that policy and current household-profile/member exceptions on the backend; an administrator-capable transport credential is still a technical principal, not a human mapping claim. Ordinary unlinked users and first-arriving browsers gain no privilege from timing. Revoked inherited grants and known suspensions cannot be revived by a cached context or receipt. +Domus remains an independent authorization boundary; consuming a service through MCP does not bypass it. +No gateway-client token or per-agent administration is implemented here. + +HA can trigger maintenance and replenishment through these commands with stable trigger identity, +cooldown, correlation and loop suppression. Domain effects are deterministic and audited. +The in-app simple/default and optional advanced editors share one Domus engine. HA rule entrypoints delegate to that engine; its schema and run policy remain authoritative. External HA automations can still call ordinary typed Domus actions, with command receipts and backend permissions intact. No HA automation YAML or gateway code is rewritten. +Disablement stops new runs and later steps, lets an already-started atomic command finish and preserves its actual receipt/effects. A response distinguishes authoritative disabled state from results still settling. Durable control revisions fence old workers, queues and waits; restart/re-enable does not silently resume cancelled runs, and no automatic rollback is claimed. +Events such as domus_task_completed, domus_inventory_low and domus_operation_updated contain +bounded IDs/revisions and safe metadata, not full private records. Projection updates never retrigger +the same causal automation indefinitely. + +## Contract verification + +Disposable HA tests verify registration, selectors, response support, UID stability, context mapping, +unload/reconnect and both deployment targets. Native task operations route through the same policies. +Shopping remains read-only in native to-do until purchase/receipt semantics are unambiguous. +Local Chrome dogfooding verifies discoverability and real user flows without changing the gateway. diff --git a/docs/copilot-adoption.md b/docs/copilot-adoption.md new file mode 100644 index 0000000..00d863b --- /dev/null +++ b/docs/copilot-adoption.md @@ -0,0 +1,48 @@ +# Adopting Copilot without changing Copilot + +## Observed installation + +Domus master initially contains the minimal README and installed Copilot resources at commit 8ee7e1a. +The repository profile enables documentation work through the installed documentation form, requires +Action-managed remote branches and declares pre-branch SDD. No SDD prerequisites exist on that baseline. + +The owner prohibits edits to Copilot's repository, code, workflows, profiles, guides, templates and scripts. +Only an existing project-owned dependency preparation file may be considered when necessary: +the inspected candidate is .github/actions/copilot-verification-setup/action.yml, currently a failing placeholder. +No changes to it are part of this documentation package. + +## Inherited specification contract + +The original specs/README.md and specs/_template.md are included as unmodified reference copies from +Copilot revision f5e5a4cf9a80248994469cd88ad55eecab5b95ca. They do not replace installed Copilot resources. +Domus SDDs retain all twenty English headings. Section 4 declares Requirement/Behavior, section 14 contains +the exact numeric budget and case inventory tables, section 15 declares Path/Change, and section 17 +provides the exact reciprocal Requirement/Cases table required by the audited consistency validator. +Every case is planned acceptance work, not a claim that tests exist. + +## Catalog limitation + +The audited SDK version-1 validator requires nonempty entrypoints, code and tests arrays for every capability, +including status proposed. Domus has no implementation files yet. The proposed catalog therefore preserves +empty arrays and an explicit readiness blocker instead of referencing fake source or calling documents code. +The original validator is run unchanged against the package; failure is recorded in the validation evidence in docs/sdd-validation.md. +A passing draft-format check cannot establish gate readiness. + +The truthful proposed-capability bootstrap limitation is reported in [Copilot issue #777](https://github.com/vypdev/copilot/issues/777), with a pinned-source reproducer. The separate opaque progress-assessment failure is tracked in [Copilot issue #774](https://github.com/vypdev/copilot/issues/774#issuecomment-6483788546). These reports are not evidence that the catalog caused the workflow's progress failure, and neither authorizes a local workaround or a Copilot edit. + +Do not patch the validator, substitute a weaker schema, change capability status, register unrelated code, +or alter any Copilot configuration to conceal this result. Resolve the supported initialization route +with the maintainer before attempting a feature gate. The current documentation issue is not marked +contract-change and needs no synthetic feature issue. + +## Contribution lifecycle + +[Documentation issue #2](https://github.com/vypdev/domus/issues/2) is the single initial work item. +A maintainer adds in-progress after admission. The Action publishes the exact linked docs branch. +Only then may a contributor check out that ref and incorporate this prepared package. No remote branch +is created, renamed, force-pushed or deleted by this contributor. +A linked PR carries validation and unresolved decisions; maintainers own merge and deployment. + +No runtime package, pnpm task or CI workflow exists in Domus yet. Commands appearing in the unchanged +upstream standard are upstream commands, not installed Domus capabilities. The draft-check runner shipped +outside this repository is a review aid and does not replace the Action's bundled authority. diff --git a/docs/decisions.md b/docs/decisions.md new file mode 100644 index 0000000..710da44 --- /dev/null +++ b/docs/decisions.md @@ -0,0 +1,67 @@ +# Decisions and readiness + +Confirmed owner requirements are recorded in [product vision](product-vision.md). They are not open questions. + +| ID | Decision / status | Reason / evaluated alternative | Readiness gate | +|---|---|---|---| +| A1 | Accepted: modular backend App/Container plus thin HA companion integration | Full UI and durable domain model; pure custom integration has a larger Core lifecycle burden | Owner confirmed 2026-10-29; implementation boundary checks remain required | +| A2 | Accepted: Python/FastAPI, SQLite and Lit/TypeScript/Vite; HA-coherent owned components, Storybook and Playwright | Converges with Gateway's implementation and Symphonia's accepted presentation contracts | Owner confirmed 2026-10-29; exact versions and supported-browser evidence remain required | +| A3 | Accepted: one household per installation; one DB writer proposed | Avoid distributed consistency and preserve a migration seam | Household scope confirmed 2026-10-29; storage concurrency verification remains required | +| A4 | Verify individual HA user identity and administrator status in both deployment targets; no local passwords/PINs | Meets confirmed own-account and administrator-mapping requirements; Ingress headers alone require a proven trusted boundary | Authentication spike and security review | +| A5 | Accepted: relative intervals use actual completed_at; per-task successor timing defaults to at_completion with at_verification available; fixed schedules preserve calendar anchors | Approval controls points and the optional release gate, never silently shifts the recurrence anchor | Owner confirmed anchor and configurable timing 2026-10-29; state/reopening fixtures remain required | +| A6 | Accepted: advance nonexistent times to the first valid local instant at or after the intended time; repeated times execute once at the first appearance by default, with a household second-appearance option | Preserve nominal identity, avoid lost/duplicate work and disclose the resolved instant | Both owner decisions confirmed 2026-10-29; library/RRULE/export interoperability evidence remains required | +| A7 | Accepted: allocation is configurable in the application; conserve_total is the initial default, with rounded equal shares, decimal shares, full_per_participant and authorized manual allocation | The owner's later clarification permits totals below, equal to or above the base task value; policy/version and actual shares are immutable award evidence | Expanded owner decision confirmed 2026-10-29; exact remainder fairness and reward review remain open | +| A8 | Accepted default: manual shopping demands are extras; automatic inventory/material needs consolidate without counting the same need twice | Keep user intent while retaining automatic-source identities and already-reserved quantities | Owner confirmed 2026-10-29; unit conversion and detailed overlap fixtures remain engineering review | +| A9 | Human HA context mapped to roles; automation uses narrow technical grants | Context does not establish per-MCP-client identity automatically | Service authorization review | +| A10 | Accepted: one Domus declarative motor with simple/default and optional advanced editors, both at first release; HA can also call public Domus actions | One versioned model preserves behavior between editors; engine policy stays separate from native HA transport | Owner confirmed 2026-10-29; DSL bounds, recovery and loop/permission evidence remain required | +| A11 | Isolated domus/domus_edge namespaces and credentials in both targets | Stable and Edge can coexist safely | Packaging and HA registry review | +| A12 | 100% supported first-party coverage metrics, with behavior-driven cases | Owner requires maximum coverage from the first code; no blanket exclusions | Quality toolchain review | +| A13 | Draft catalog retains empty implementation evidence until it exists | Audited SDK validator rejects empty code/entrypoints/tests even for proposed capabilities | Gate readiness blocked; do not change Copilot | +| A14 | Accepted: camera scan, manual entry, local catalog and optional Internet product lookup | Local operation remains useful without an external provider; candidates retain provenance and require schema validation | Owner completed barcode scope 2026-10-29; provider feasibility/terms, library and device evidence remain required | +| A15 | Accepted defaults: adults complete without verification; restricted performers need adult approval | Resolve effective verification from the actual performers and authorized policy, not just the submitter's role | Owner confirmed 2026-10-29; explicit task overrides and permission contracts require tests | +| A16 | Accepted: adjustable actual material quantities in the completion form and the same submission, configurable per task | Keep one household action while Inventory owns explicit, attributable consumption and per-line receipts | Owner confirmed 2026-10-29; combined-command permission/recovery contracts require tests | +| A17 | Accepted: insufficient stock saves performed work and a consumption intent pending regularization; no negative stock | Recording completed work must not fabricate stock or conceal unresolved materials | Owner confirmed 2026-10-29; explicit settlement and concurrent/replayed operations require tests | +| A18 | Accepted: reverse already-spent task points in full, allow a factual negative balance, block new redemptions until recovered and retain fulfilled rewards | Preserve ledger truth without retracting delivered rewards or suppressing a correction | Owner confirmed 2026-10-29; unfulfilled rewards follow the accepted funding hold in A24 | +| A19 | Accepted: missed fixed-schedule occurrences are configurable per task; retain all visibly pending by default with explicit skip available | A missed chore must not become a fabricated completion or point award | Owner confirmed 2026-10-29; resume/overlap preview and alternative policy details require tests/review | +| A20 | Accepted: recurrence edits preview the delta and update only unstarted future occurrences, preserving started work and history | Avoid changing work underway while allowing future schedules to follow the updated rule | Owner confirmed 2026-10-29; stale previews, retained exceptions and replacement identities require tests | +| A21 | Accepted: earned points and participation use the actual-work period; required approval controls when credit becomes spendable | A Sunday completion approved Monday belongs to Sunday's week without spending unapproved points | Owner confirmed 2026-10-29; reporting, posting and reversal timestamps require boundary fixtures | +| A22 | Accepted: reopening a prerequisite preserves completed downstream work and its points, flags the changed dependency and requests review without automatic reopening in a chain | A changed prerequisite does not erase work actually performed or fabricate downstream compensation | Owner confirmed 2026-10-29; revision/attention and recovery fixtures remain required | +| A23 | Accepted: disabling a rule stops new runs and subsequent steps, lets an already-started atomic command finish and retains its effects | Make the stopping boundary explicit without claiming rollback of committed actions | Owner confirmed 2026-10-29; admission races, parallel branches and restart fencing require evidence | +| A24 | Accepted: an approved unfulfilled reward without sufficient backing enters a funding hold until credit recovers or an explicit authorized resolution occurs; delivery remains blocked while unfunded | Preserve approval/reservation without automatic cancellation, delivery or fabricated credit | Owner confirmed 2026-10-29; reversal/fulfillment/cancellation races require tests | +| A25 | Accepted: all_ha_administrators is the default administrator mapping; setup_administrator and selected_ha_user are supported configuration alternatives | The owner explicitly requested all three modes and selected the all-HA-administrators mode as default | Owner confirmed 2026-10-29; authoritative HA proof, source revocation and authenticated recovery require evidence | +| A26 | Accepted: predefined permission profiles are adjustable per household with explicit per-member exceptions | Households can tailor grants without replacing verified identity or domain invariants | Owner confirmed 2026-10-29; detailed permission matrix, deterministic precedence and cache/revocation tests remain required | + +All eleven SDDs remain Draft. Review resolves choices; it does not claim implementation or live acceptance. +The Copilot limitation is an observed constraint, not permission to change its implementation, +installed files, statuses, or checks. Documentation can be reviewed through its existing documentation workflow. + +## Review status + +The latest owner-question batches are answered and recorded in A6 and A22–A26. Administrator mapping supports all three requested modes; the default is all_ha_administrators, superseding the installer's-only recommendation from the question. + +All SDDs remain Draft. Authentication/administrator proof and recovery, the detailed permission matrix, time-zone/library interoperability, adapter feasibility and numeric resource bounds still need explicit engineering/security review and executable evidence. These gates do not reopen the accepted architecture, product policies or launch scope. + +## Owner decisions recorded on 2026-10-29 + +- Nonexistent local task times advance to the first valid instant at or after the intended wall time on that date. For example, a 02:30 task in a 02:00–03:00 clock gap runs at 03:00, not at midnight and not twice. The adjustment is visible and retains the nominal occurrence key. +- Collaborative points are configurable in the application. The initial default shares one conserved total, but households may select equal shares rounded down/up, decimal shares, full task points per participant or authorized manual amounts. For a base of ten and three performers, supported examples include 3/3/4, 3/3/3, 4/4/4, 3.33/3.33/3.33 and 10/10/10. This later clarification supersedes conservation as a universal invariant. Award history retains base value, policy/version, precision, shares and actual total. +- The owner confirmed Lit/TypeScript/Vite, a Home Assistant-coherent visual direction with Domus-owned presentation components, Storybook and Playwright after reviewing Symphonia and Gateway. Their examples are evidence, not a private HA component dependency or an inherited version/support promise. +- The owner confirmed Python/FastAPI, SQLite, a thin HA integration and one household per installation. Exact toolchain versions, migrations, authentication proof and writer concurrency remain engineering verification gates. +- Adults need no task-completion verification by default; restricted performers need approval by an authorized adult. Points wait for that required approval. Explicit administrator-controlled overrides remain a documented configuration concern. +- Barcode entry includes camera scan and manual input, local matching and optional Internet lookup. The provider itself remains unselected pending feasibility, terms and security review. +- Completion-relative schedules anchor to actual completed_at; a delayed approval never shifts the next scheduled date. +- Manual shopping requests are additional by default. Automatic stock/material requirements consolidate against their source/coverage identity without counting the same need twice. +- Both automation editors are first-release features: simple is the default and advanced is optional. They share one declarative engine; switching editor cannot discard advanced rule fields. +- Successor timing is configurable per task: show it when completion is recorded by default, or wait for approval. Both choices calculate its date from actual work completion; waiting for approval does not move that date. +- Task materials default to a review of adjustable actual quantities in the completion form, recorded with the same submission and configurable per task. Inventory owns movements and permissions; reopening does not imply a physical return. +- Insufficient material stock leaves the work completed and its consumption pending regularization, without a negative stock movement. Pending material, verification and points outcomes remain independently visible. +- Reopening reverses points even when already spent. Preserve a resulting negative balance, block new redemptions until the deficit is recovered and sufficient points exist, and retain already-fulfilled rewards. +- Fixed-schedule missed occurrences are configurable per task. Keep all pending occurrences visible by default; explicitly skipping one preserves its history and awards no completion points. +- Recurrence edits show a preview and update only unstarted future occurrences, retaining started work and history. A concurrent start invalidates the preview rather than allowing a silent overwrite. +- Earned points and participation belong to the actual-work week/month in the household zone; required approval makes credit spendable later without moving its reporting period. Keep completed_at, verified_at and ledger posted_at distinct. +- Reopening a prerequisite retains already-completed dependent work and points and raises a review condition; there is no automatic chain of reopening or compensation. +- Disabling a rule stops new runs and later steps, lets an already-started atomic command finish and preserves its effects. Restart/re-enable must not silently resume cancelled work. +- Approved rewards whose backing points were reversed wait for sufficient credit or an explicit authorized resolution. Keep approval and reservation; do not deliver while unfunded or cancel silently. +- Administrator mapping is configurable: all HA administrators by default, only the verified setup administrator, or an explicitly selected HA user. Prove identity and the relevant HA privilege; retain each grant's source and enforce revocation. +- Predefined administrator/adult/restricted/viewer profiles support household adjustments and per-member exceptions. Backend authorization, scope, ledger integrity and required adult verification remain enforced. +- Repeated autumn wall times execute once at the first appearance by default, with a household option for the second. Preserve nominal identity and disclose the resolved instant. diff --git a/docs/evidence/sdd-validation.json b/docs/evidence/sdd-validation.json new file mode 100644 index 0000000..b5d3256 --- /dev/null +++ b/docs/evidence/sdd-validation.json @@ -0,0 +1,261 @@ +{ + "referenceRevision": "f5e5a4cf9a80248994469cd88ad55eecab5b95ca", + "prerequisiteStructure": "PASS", + "drafts": [ + { + "id": "platform-foundation", + "path": "specs/platform-foundation.md", + "requirements": 6, + "cases": 20, + "characters": 25661, + "status": "PASS" + }, + { + "id": "household-identity", + "path": "specs/household-identity.md", + "requirements": 7, + "cases": 30, + "characters": 34606, + "status": "PASS" + }, + { + "id": "household-tasks", + "path": "specs/household-tasks.md", + "requirements": 9, + "cases": 38, + "characters": 35269, + "status": "PASS" + }, + { + "id": "recurrence-calendar", + "path": "specs/recurrence-calendar.md", + "requirements": 8, + "cases": 37, + "characters": 35737, + "status": "PASS" + }, + { + "id": "points-rewards", + "path": "specs/points-rewards.md", + "requirements": 6, + "cases": 44, + "characters": 39241, + "status": "PASS" + }, + { + "id": "shopping-management", + "path": "specs/shopping-management.md", + "requirements": 7, + "cases": 21, + "characters": 25500, + "status": "PASS" + }, + { + "id": "household-inventory", + "path": "specs/household-inventory.md", + "requirements": 8, + "cases": 35, + "characters": 33096, + "status": "PASS" + }, + { + "id": "home-assistant-surface", + "path": "specs/home-assistant-surface.md", + "requirements": 8, + "cases": 33, + "characters": 32547, + "status": "PASS" + }, + { + "id": "application-experience", + "path": "specs/application-experience.md", + "requirements": 6, + "cases": 26, + "characters": 28218, + "status": "PASS" + }, + { + "id": "delivery-quality", + "path": "specs/delivery-quality.md", + "requirements": 8, + "cases": 24, + "characters": 26444, + "status": "PASS" + }, + { + "id": "household-automation", + "path": "specs/household-automation.md", + "requirements": 9, + "cases": 45, + "characters": 33902, + "status": "PASS" + } + ], + "totalCases": 353, + "totalRequirements": 82, + "catalog": { + "status": "BLOCKED", + "errors": [ + "capabilities[0].entrypoints must not be empty.", + "capabilities[0].code must not be empty.", + "capabilities[0].tests must not be empty.", + "capabilities[1].entrypoints must not be empty.", + "capabilities[1].code must not be empty.", + "capabilities[1].tests must not be empty.", + "capabilities[2].entrypoints must not be empty.", + "capabilities[2].code must not be empty.", + "capabilities[2].tests must not be empty.", + "capabilities[3].entrypoints must not be empty.", + "capabilities[3].code must not be empty.", + "capabilities[3].tests must not be empty.", + "capabilities[4].entrypoints must not be empty.", + "capabilities[4].code must not be empty.", + "capabilities[4].tests must not be empty.", + "capabilities[5].entrypoints must not be empty.", + "capabilities[5].code must not be empty.", + "capabilities[5].tests must not be empty.", + "capabilities[6].entrypoints must not be empty.", + "capabilities[6].code must not be empty.", + "capabilities[6].tests must not be empty.", + "capabilities[7].entrypoints must not be empty.", + "capabilities[7].code must not be empty.", + "capabilities[7].tests must not be empty.", + "capabilities[8].entrypoints must not be empty.", + "capabilities[8].code must not be empty.", + "capabilities[8].tests must not be empty.", + "capabilities[9].entrypoints must not be empty.", + "capabilities[9].code must not be empty.", + "capabilities[9].tests must not be empty.", + "capabilities[10].entrypoints must not be empty.", + "capabilities[10].code must not be empty.", + "capabilities[10].tests must not be empty." + ] + }, + "sources": [ + { + "path": "src/domain/pre_branch_sdd.ts", + "sha": "17d2d99471f7371a393c2976bf9fd30ca63e2c83", + "url": "https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/domain/pre_branch_sdd.ts", + "sha256": "636db20b18cd7b694c2d68e2d5fc53f5387daae90bcb231c98c2c2534d6125c3" + }, + { + "path": "src/domain/sdd_draft_consistency.ts", + "sha": "c1487eac45d12911052df9ce72ac1cdcb54e0b96", + "url": "https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/domain/sdd_draft_consistency.ts", + "sha256": "04b6c1eebee7284270b8ad08107c2b2d01c4b3d059d5603a4eecab92616223fd" + }, + { + "path": "src/domain/sdd_catalog_compatibility.ts", + "sha": "b63305a368e68ff6cf7b1689a604d004765ff48e", + "url": "https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/domain/sdd_catalog_compatibility.ts", + "sha256": "0036d4417892aa35ed450a43b696bae02154a073f4723916a5ada8c53ca1f0eb" + }, + { + "path": "src/domain/sdd_validation_diagnostic.ts", + "sha": "af7888055cc9d13547afd8482045639d78a4552d", + "url": "https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/domain/sdd_validation_diagnostic.ts", + "sha256": "1906276928b2fae7d81855da29a67154abad22bd0eaab1c7046fe4b67afb30b8" + }, + { + "path": "src/domain/specification_catalog_path_policy.cjs", + "sha": "3232beb9092401cab6a033ebb9434f9ae3117d03", + "url": "https://github.com/vypdev/copilot/blob/master/src/domain/specification_catalog_path_policy.cjs", + "sha256": "263227b049b5aa2ebdfa9c44ae1e10eaa541c87fdb8d01644856493018b2aca7" + }, + { + "path": "src/domain/sdd_prerequisite_policy.cjs", + "sha": "06b58c28ff34fa15b662ea9ace69bf0a72ed522f", + "url": "https://github.com/vypdev/copilot/blob/master/src/domain/sdd_prerequisite_policy.cjs", + "sha256": "e4224fd266a82eb6ec34dc4471d92d8bf48629fc99723f0696bfed8ac1c2ee70" + }, + { + "path": "src/infrastructure/specification_catalog_validator.cjs", + "sha": "7e32e203d5cf2e71f3a944e05c461a3e7f73a903", + "url": "https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/infrastructure/specification_catalog_validator.cjs", + "sha256": "2310e14413baeba83d474f3b4d58944e18df19d3ec0c82a948157a8de0ec774c" + } + ], + "applicationTests": "NOT IMPLEMENTED", + "liveDogfooding": "NOT RUN", + "copilotChanged": false, + "auditedAt": "2026-10-29", + "pullRequestCheckAudit": { + "pullRequest": "https://github.com/vypdev/domus/pull/3", + "reviewedHead": "fa7adf1118b85e1588f0de7d71a77f47822b5000", + "workflowRun": "https://github.com/vypdev/domus/actions/runs/40774284194", + "initialAttempt": { + "conclusion": "failure", + "code": "agent.failed", + "stage": "progress assessment", + "diagnostic": "assessment-invalid", + "applicationTestFailure": false + }, + "retryAttempt": { + "number": 2, + "conclusion": "success", + "job": "https://github.com/vypdev/domus/actions/runs/40774284194/job/123154135293", + "verification": "success" + }, + "review": { + "conclusion": "neutral", + "meaning": "Review skipped because the PR remains a draft; not a clean-review claim" + }, + "copilotChanges": false + }, + "subsequentHeadCheckAudit": { + "reviewedHead": "ce2871b15508a1de53eaceca9bada001b31c25f2", + "workflowRun": "https://github.com/vypdev/domus/actions/runs/40787905127", + "attempts": [ + { + "number": 1, + "conclusion": "failure", + "job": "https://github.com/vypdev/domus/actions/runs/40787905127/job/123165609347" + }, + { + "number": 2, + "conclusion": "failure", + "job": "https://github.com/vypdev/domus/actions/runs/40787905127/job/123168549416" + } + ], + "stage": "progress assessment", + "diagnostic": "assessment-invalid", + "publishedCode": "agent.failed", + "applicationTestFailureIdentified": false, + "copilotChanges": false, + "scope": "Historical head only; the next documentation commit has independent checks." + }, + "upstreamReports": { + "progressAssessment": "https://github.com/vypdev/copilot/issues/774#issuecomment-6483788546", + "proposedCatalogBootstrap": "https://github.com/vypdev/copilot/issues/777" + }, + "acceptedDecisionTableRows": [ + "A1", + "A2", + "A3", + "A5", + "A6", + "A7", + "A10", + "A14", + "A15", + "A16", + "A17", + "A18", + "A19", + "A20", + "A21", + "A22", + "A23", + "A24", + "A25", + "A26" + ], + "latestOwnerReview": [ + "A6", + "A22", + "A23", + "A24", + "A25", + "A26" + ] +} diff --git a/docs/glossary.md b/docs/glossary.md new file mode 100644 index 0000000..6efabf7 --- /dev/null +++ b/docs/glossary.md @@ -0,0 +1,41 @@ +# Shared domain glossary + +| Term | Meaning and owner | +|---|---| +| Household | One installation's scope for records and permissions | +| Principal | Verified human or technical identity; never a caller-supplied name | +| Member | Household participant linked to their own distinct HA account | +| HA person | Optional presence/profile entity; not an authentication credential | +| Task definition | Reusable responsibility, policy and version | +| Task occurrence | A specific execution with stable identity and independent history | +| Assignee | Planned responsible member | +| Actual performer | Member who did the work; may differ from the assignee | +| Completion actor | Authenticated principal recording completion | +| Completion cycle | Stable accepted performance identity; reopening closes it and a genuine later completion gets a new ID | +| Verifier | Authorized principal approving completion when required | +| Permission profile | Predefined role with administrator-adjustable household grants, subject to explicit member exceptions and hard domain constraints | +| Inherited administrator grant | Domus administration derived from a verified HA source under the configured mapping policy, with provenance and current revocation checks | +| Dependency attention | Separate review condition retaining completed downstream work after its prerequisite changes | +| Due date | Deadline; distinct from scheduled start and actual completion | +| Demand | Attributable purchasing intent with additional/overlapping semantics | +| Shopping line | Reversible aggregation of compatible demands, retaining sources | +| Purchase | Recorded acquisition commitment; not proof of physical receipt | +| Receipt | Confirmed physically received quantity | +| Product | Identity of a supply, independent of package presentation | +| Presentation | Package size and exact conversion to the product base unit | +| Stock movement | Immutable receipt, consumption, transfer or correction entry | +| Material consumption intent | Explicit actual-usage submission linked to a completion cycle and line; may await regularization without being a posted movement | +| Pending regularization | Performed work is saved but an inventory discrepancy needs authorized factual review before the material intent can be settled | +| Reservation | Stock allocated to a material requirement | +| Available stock | Physical stock minus active reservations | +| Points entry | Immutable award, reversal or correction with a unique source | +| Base task points | Nominal task value before the selected collaborative allocation policy | +| Actual awarded total | Sum of immutable performer shares; may differ from base points according to the configured policy | +| Allocation policy | Versioned household rule for conserving, rounding, decimal, full-performer or authorized manual awards | +| Funding hold | Approved but unfulfilled redemption lacking sufficient backing; approval/reservation persist while delivery is blocked | +| Outbox / inbox | Durable event publication and deduplicated consumption records | +| Projection | Rebuildable read model; not another source of business truth | +| Stable | Production channel with a versioned accepted artifact | +| Edge | Experimental channel, isolated from production data and credentials | +| CI Check | Project-owned verification workflow; separate from immutable Copilot automation | +| Dogfooding | Controlled real use in the owner's local HA through Google Chrome | diff --git a/docs/operations.md b/docs/operations.md new file mode 100644 index 0000000..77b227a --- /dev/null +++ b/docs/operations.md @@ -0,0 +1,68 @@ +# Proposed setup and operations guide + +This guide describes intended operation. No Domus artifact is installed or deployed yet. + +## Recommended setup + +Choose Supervisor App/Ingress or standalone Container. Both ship in the first usable release. +Choose Stable for production or isolated Edge for experimental validation. Create one household and time zone, +then link each participating member to their own verified HA account and assign explicit Domus roles. +Optional person associations supply profile/presence data only. + +Supervisor stores Domus data in its own persistent application namespace and exposes the UI through Ingress. +Standalone uses a private host binding, authenticated access and an owned volume, connecting to HA Core +without assuming Supervisor services. No direct browser identity headers establish trust. +Validate the chosen target's authentication, persistence and native HA integration before declaring setup complete. + +## Permissions and configuration + +Administrators manage membership, point policies, verification, corrections and automation grants. +Collaborative points policy is configured in the application. The preview discloses base points, rounding/precision, performer shares and actual total; only an authorized configuration change selects a different policy. Existing awards retain their snapshots, and reopening reverses the amounts actually awarded. Restricted performers need adult approval by default, while adults do not. + +Task completion reviews adjustable actual materials in the same submission by default, with a per-task separate-recording option. A stock shortfall saves performed work and a pending-regularization intent without a stock movement. Review its source and actual inventory facts before authorized settlement; restocking alone does not post the old usage. Reopening does not return materials automatically. Reversal of already-spent points can create a factual negative balance; retain delivered rewards and block new redemption until sufficient unreserved points exist. +Adults perform authorized household commands; restricted and viewer roles use the reviewed permission matrix. +Technical HA commands use explicit grants without impersonating members. Domain forms do not accept tokens. +Optional product lookup is configured through a bounded provider adapter; no external catalog is mandatory. Keep camera frames, household identity and stock history local. Provider failure leaves camera/manual entry and local catalog search usable. +Invalid or unknown configuration versions block the affected operation and preserve prior settings. + +Administrator mapping defaults to all_ha_administrators; setup_administrator and selected_ha_user are explicit alternatives. Verify current HA identity/administrator status through the reviewed adapter, retain grant provenance and revoke invalid inherited grants. Household role profiles and member exceptions are configurable through current administrator authority; known suspension and hard domain constraints remain enforced. Changing a mapping or profile through Domus cannot remove its last active effective administrator. External HA account loss requires the reviewed authenticated recovery procedure, never a browser-order fallback. + +Reopening a prerequisite preserves already-completed downstream work and points and raises dependency_attention. Approved unfulfilled redemptions without backing enter funding_hold with approval/reservation retained; delivery cannot proceed until funding is sufficient or an explicit authorized resolution occurs. Disabling a rule fences new admissions and subsequent steps while recording the result of already-started atomic commands. Restart/re-enable does not silently resume its cancelled queue or waits. + +## Recovery + +| Symptom | Retained fact | Next action | +|---|---|---| +| Lost save response | Operation may already be committed | Look up the operation or replay its original idempotency key | +| Stale task or stock revision | Latest backend record is intact | Review current state before deliberate resubmission | +| Receipt saved, stock missing | Physical receipt is recorded; posting is pending | Retry only the identified stock post | +| Task saved, material stock insufficient | Work completion and pending material intent persist; no negative stock was invented | Review actual inventory facts and explicitly resolve the retained intent | +| Negative points after reopening | Actual reversal and delivered reward remain recorded | Earn points to cover the deficit; new redemption requires sufficient unreserved credit | +| Completed work has dependency attention | Real downstream completion, points and material facts persist | Review the linked reopened prerequisite; do not cascade reopening automatically | +| Approved reward has a funding hold | Approval and reservation persist; delivery has not occurred | Recover sufficient credit or explicitly review/cancel; do not bypass affordability | +| Rule disabled with a settling command | New work is fenced; the started command's actual result remains | Inspect the retained receipt; do not resume cancelled waits on re-enable | +| HA unavailable | Domain records persist; native projections may be stale | Restore HA connectivity and reconcile projections | +| Schema too new | Database remains intact; writes are blocked | Use a compatible application or restore the paired backup | +| Insufficient role | No denied command effect was committed | Ask an administrator to review access | + +Backoff is bounded. Repeated availability failures become an actionable status rather than endless notifications. +Routine activity/log retention never deletes the command guards needed to prevent duplicate effects. Receipt access remains subject to current permissions, including after suspension. +Logs use safe error codes and correlation IDs; exported diagnostics exclude credentials and unnecessary household details. + +## Backup, upgrade and rollback + +Back up the consistent database, required media, schema manifest and installation configuration. +Encrypt sensitive backup material and retain local ownership. Verify backup integrity in an isolated restore. +Stable and Edge never share credentials, DB volumes or household mutations. Restoring a copy into Edge +requires an explicit import/sanitization operation; it must not retain production service credentials. +Schema-incompatible downgrade requires the paired data backup; never run old code against newer schemas blindly. + +## Authorized local dogfooding + +The owner permits Google Chrome at http://homeassistant.local:8123/. +Before mutation, identify the Domus channel/artifact and create records with a unique domus-dogfood run label. +Track each created ID and any ledger compensation. Exercise normal, denied, replay, offline, partial and recovery paths. +Clean only recorded test-owned artifacts through supported domain operations. Do not bulk-clear native shopping lists, +delete real household records, change gateway policy, install/promote production, or expose secrets in evidence. +Record retained fixtures if a cleanup fails; no clean-state claim is made until reconciled. +This authorization enables controlled functional use, not an unrelated production deployment. diff --git a/docs/product-vision.md b/docs/product-vision.md new file mode 100644 index 0000000..c372c08 --- /dev/null +++ b/docs/product-vision.md @@ -0,0 +1,78 @@ +# Domus — Your home. In harmony. + +Domus is a local household management application for Home Assistant. It unifies tasks, +calendar planning, shopping, inventory, family participation and automation through its own UI. +Ordinary workflows work without AI, external calendars or Internet services. + +## Confirmed owner decisions + +- The first usable release covers all six functional domains. +- Both Supervisor-managed App/Ingress and standalone Container are first-release targets. +- Every participating member has their own Home Assistant account. +- The existing gateway is already integrated in HA. Domus defines entities and services for it to consume. +- All issues, documentation, code, identifiers and comments are English; conversation with the owner is Spanish. +- Clean Architecture is mandatory. Every implementation starts with tests and maximum coverage. +- Stable production and experimental development channels are required, as in the gateway. +- A project workflow named CI Check runs all tests on each PR update. +- Google Chrome dogfooding is authorized at http://homeassistant.local:8123/. +- Copilot is immutable, except a narrowly reviewed project dependency-preparation setup file if needed. +- Nonexistent local task times advance to the first valid instant at or after their intended wall time; the task is not silently dropped (confirmed 2026-10-29). +- Collaborative allocation is configurable in the application: conserve one task total by default, or choose rounded/decimal equal shares, full points per participant or authorized manual shares. Show the actual total and preserve the chosen policy with each award (expanded owner decision 2026-10-29). +- The selected architecture is Python/FastAPI with SQLite, a thin HA companion integration and one household per installation (confirmed 2026-10-29). +- The UI uses Lit/TypeScript/Vite, Domus-owned HA-coherent components, a Storybook catalog and Playwright browser tests (confirmed 2026-10-29). +- Adults complete tasks without verification by default; restricted performers need adult approval before points are awarded (confirmed 2026-10-29). +- Barcode workflows include camera scan, manual entry, local catalog search and optional Internet product lookup; no external provider is mandatory (confirmed 2026-10-29). +- Completion-relative schedules count from actual work completion rather than its later approval (confirmed 2026-10-29). +- Manual shopping requests are extras by default; automatic inventory/material needs consolidate without double-counting a source requirement (confirmed 2026-10-29). +- Simple/default and optional advanced automation editors are both included in the first release over one shared declarative engine (confirmed 2026-10-29). +- Relative tasks show their next occurrence when work is recorded by default; each task may instead wait for approval without changing the actual-completion date anchor (confirmed 2026-10-29). +- Material quantities are reviewed and adjustable when completing a task, with both recorded in the same submission; the task configuration can use separate recording instead (confirmed 2026-10-29). +- Material stock shortfalls do not block recording performed work: save consumption pending regularization without inventing negative stock (confirmed 2026-10-29). +- Reopening reverses the actual point award even if spent; a factual negative balance blocks new redemptions until recovered while delivered rewards remain delivered (confirmed 2026-10-29). +- Missed fixed-schedule occurrences are configurable per task; the default keeps all visible with explicit skip available, retaining history without completion points (confirmed 2026-10-29). +- Recurrence changes show a preview and update only future executions that have not started, preserving started work and history (confirmed 2026-10-29). +- Participation and earned points belong to the actual-work period; required approval controls when points become spendable without moving them to the approval week (confirmed 2026-10-29). +- Reopening a prerequisite preserves completed dependents and their points and raises a review condition rather than automatically reopening a chain (confirmed 2026-10-29). +- Disabling automation stops new runs and subsequent steps while an already-started atomic command finishes and retains its effects (confirmed 2026-10-29). +- Approved unfulfilled rewards without sufficient backing wait for credit recovery or an explicit authorized resolution; delivery is blocked while unfunded (confirmed 2026-10-29). +- Administrator mapping supports all HA administrators by default, the verified setup administrator only, or an explicitly selected HA user (confirmed 2026-10-29). +- Predefined permission profiles are adjustable per household with explicit per-member exceptions (confirmed 2026-10-29). +- Repeated autumn times execute once at the first appearance by default; the household may select the second (confirmed 2026-10-29). + +## Source boundary + +The attachment contains sections 1–10.1 and the beginning of 10.2. It ends after +“Support common product identifiers such”. Missing text is not treated as an instruction. +The owner completed the barcode scope on 2026-10-29 as recorded above; provider/library selection, +lot allocation and several limits still require explicit engineering proposals and review. + +## Connected domains + +| Domain | Authoritative facts | Cross-domain link | +|---|---|---| +| Household tasks | Definitions, occurrences, assignments and actual completion | Calendar, materials and point awards | +| Family calendar | Schedules, exceptions and date/time projections | Task occurrences and completion history | +| Shopping | Demands, planning, purchases and physical receipt | Materials and replenishment | +| Inventory | Product identity, presentations, locations and stock ledger | Receipt, consumption and demand | +| Family and participation | Verified HA identity mapping, permissions and points ledger | Authorship, effort and optional rewards | +| Automation and intelligence | Deterministic HA-facing triggers, actions and audit | All domain commands, without a second MCP | + +Maintenance is represented through tasks, linked equipment/entities and material requirements. +Initial inventory prioritizes durable products while optional lots allow later perishable tracking. +Rewards, predictions and external calendar sync remain optional advanced extensions as described in the brief; +all domains themselves are included at launch. + +## Product boundaries + +Local-first means a local authoritative server and owned data, not an unreviewed offline-write sync protocol. +One household per installation is confirmed. Child/restricted members still use their own HA accounts. +A person entity is optional profile/presence metadata and never a login. +Points help explain participation; task counts, estimated effort and workload remain visible. + +## First integrated release acceptance + +A member creates a scheduled maintenance task requiring a stock item, claims/completes the occurrence, +records material consumption, earns verified ledger points, sees the calendar/history, receives a low-stock +shopping requirement, purchases and receives the replacement, and verifies HA entities/services. +The same business fixtures pass on both deployment targets and channels. Internal milestones are not separate +partial product releases. See [roadmap](roadmap.md) and [architecture](architecture.md). diff --git a/docs/reference-investigation.md b/docs/reference-investigation.md new file mode 100644 index 0000000..32e2b48 --- /dev/null +++ b/docs/reference-investigation.md @@ -0,0 +1,71 @@ +# Reference investigation + +Audited 2026-10-28. Neither reference repository was modified. +Copilot source revision: f5e5a4cf9a80248994469cd88ad55eecab5b95ca. +Gateway source revision: 9d4e159182f7c955406c37fd372ee3ec50ed2b87. + +## Copilot conventions actually inspected + +| Source | Observed convention | Domus adoption | +|---|---|---| +| [Specification standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md) | Product contract, architecture, UX, configuration, numeric tests, acceptance and documentation | Unmodified reference copy plus proportionate prospective SDDs | +| [Template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md) | Twenty numbered English sections and explicit review metadata | Exact original headings and Draft status | +| [Product specification skill](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/.agents/skills/product-specification/SKILL.md) | Evidence first; pure rules, ports, bounded configuration, user states and review gates | Applied to authoring; no competing methodology | +| [Catalog validator](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/infrastructure/specification_catalog_validator.cjs) | SDK v1 statuses, real paths, unique ownership and generated catalog | Preserve proposed status; expose missing implementation evidence | +| [Draft consistency policy](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/src/domain/sdd_draft_consistency.ts) | Requirement/Behavior; case inventory/budget; Path/Change; reciprocal Requirement/Cases | Exact table shapes, full IDs and explicit created documentation paths | +| [Pre-branch guide](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/docs/issues/pre-branch-sdds.mdx) | Feature/contract-change clarification before first SDD branch commit | Existing documentation workflow for this foundation; no invented feature branch | +| [Specification lifecycle](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/docs/development/specifications.mdx) | Update contract, tests, implementation and docs together | Ownership and lifecycle retained | + +Observed SDK limitation: entrypoints/code/tests arrays must be nonempty even for proposed entries. +This product has none yet. The proposal does not disguise documents as code or change Copilot to bypass it. +SDD format consistency, catalog validity, branch readiness and product acceptance are different claims. + +## Gateway patterns actually inspected + +| Concern | Primary source and observation | Adopt / differ | +|---|---|---| +| Application packaging | [App config](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/addon/config.yaml), [deployment targets](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/deployment-targets.md): App plus standalone deployment, owned persistent data | Both are confirmed Domus launch targets | +| Backend | [Architecture](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/architecture.md), [HTTP composition](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/src/homeassistant_gateway/presentation/http.py): FastAPI entrypoints and semantic application ports | Reuse boundary principles; richer Domus domain and transactional ledgers | +| Frontend | [Design](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/frontend-design.md), [package](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/frontend/package.json): Lit/TS/Vite, public theme tokens, i18n, browser/architecture checks | Proposed stack, own household design; no private frontend imports | +| Auth and structured errors | [Security model](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/security-model.md): separate trust boundaries, bounded results, redaction and audit | Per-member Domus roles and technical service scope; no gateway token lifecycle work | +| HA discovery/actions | [Task/shopping guide](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/consumer/tasks-and-shopping-lists.md): services, native item UIDs and response contracts | Domus exposes its own authoritative entities/services; unrelated native lists are not silently mirrored | +| Jobs and persistence | Architecture describes process-local console jobs and SQLite adapters | Business scheduler/outbox are durable in Domus; restart-loss semantics are unsuitable | +| Channels | [Stable/Edge guide](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/docs/release-channels.md), [Edge config](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/addon-edge/config.yaml): distinct slugs, images, data and host ports | Adopt isolation, immutable source evidence and experimental designation | +| Development/testing | [CI](https://github.com/vypdev/homeassistant-gateway/blob/9d4e159182f7c955406c37fd372ee3ec50ed2b87/.github/workflows/ci.yml): backend, frontend, packaging and browser checks | Domus CI Check and owner-required maximum coverage; do not copy an 85% threshold | + +The gateway channel guide contains historical branch statements that disagree with some source comments. +Domus will derive release sources from its actual installed branch configuration, not copy those comments. +Research establishes patterns, not deployed compatibility. The owner states the gateway is already integrated; +gateway installation, modification and MCP transport are out of scope. + +## Official platform references + +- [HA Apps](https://contributors.home-assistant.io/apps/) establishes the Supervisor-managed packaging boundary. +- [Ingress](https://contributors.home-assistant.io/apps/guides/ingress/) is the App UI transport reference. +- [Authentication API](https://contributors.home-assistant.io/core/internals/auth-api/) is the basis for individual HA identity. +- [Integration actions](https://contributors.home-assistant.io/core/integrations/actions/) guides public service registration and responses. +- [Calendar entity](https://contributors.home-assistant.io/core/entities/calendar/) and [to-do entity](https://contributors.home-assistant.io/core/entities/todo/) guide projections. +- [RFC 5545](https://www.rfc-editor.org/info/rfc5545/) guides fixed calendar recurrence. + +These platform contracts require disposable-instance tests before supported-version claims. + +## Additional UI comparison requested by the owner — 2026-10-29 + +Symphonia was inspected at revision f780ea378db1b80b67214647583157aee3a5a858. Its +[accepted stack ADR](https://github.com/vypdev/symphonia/blob/f780ea378db1b80b67214647583157aee3a5a858/docs/decisions/0005-lit-typescript-vite-ui.md) +selects Lit/TypeScript/Vite, the same direction as Gateway. Its +[visual/interactions ADR](https://github.com/vypdev/symphonia/blob/f780ea378db1b80b67214647583157aee3a5a858/docs/decisions/0004-home-assistant-native-ui.md) +adds owned presentation primitives and a Home Assistant-coherent visual contract without private frontend imports. +The [isolated build spike](https://github.com/vypdev/symphonia/blob/f780ea378db1b80b67214647583157aee3a5a858/docs/development/ui-lit-spike/README.md) +is limited evidence, not proof that the complete application UI or HA/browser matrix is implemented. +The owner selected this direction for Domus with Storybook and Playwright on 2026-10-29. + +| Concern | Evidence / lesson | Domus contract | +|---|---|---| +| Framework | Gateway implements Lit/TS/Vite; Symphonia records the same accepted direction | Use the selected stack; do not copy dependency versions or assume a shared runtime component library | +| Presentation | Symphonia separates semantic tokens/primitives from feature controllers and clients | Domus owns HA-coherent components; Storybook isolates their states and Playwright exercises them | +| Host context | [Symphonia's evidence](https://github.com/vypdev/symphonia/blob/f780ea378db1b80b67214647583157aee3a5a858/docs/development/ui-spike/host-context-evidence.md) does not establish that theme, locale or identity are forwarded to App iframes | Validate any public source/origin/shape; preserve member/browser fallbacks and never use UI hints as authorization | +| Ingress and mobile | Relative Vite assets alone do not prove reload/deep-route behavior; safe-area padding has a host contract | Test non-root route reload and all request paths; apply safe-area insets once | +| Private HA controls | [Official component notice](https://contributors.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4/) warns that built-in component APIs are unstable for extensions | No private imports, parent-DOM access or private host storage dependencies | + +This comparison changes Domus design evidence and acceptance cases only. Neither reference project nor Copilot was modified. diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..ad08417 --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,19 @@ +# Development sequence and first-release gate + +The first usable release includes every functional domain, both deployment targets and both channels. +The following milestones are internal integration steps, not proposals to drop launch scope. + +| Milestone | Contract and implementation | Exit evidence | +|---|---|---| +| M0 — Specification foundation | Research, vision, eleven Draft SDDs, decisions and review | Format/traceability checks; explicit unresolved items | +| M1 — Tested platform | Identity, persistence, architecture rules, CI Check and channel isolation | 100% supported coverage; restart, migration and deployment fixtures | +| M2 — Household work | Members, tasks, recurrence, calendar, points | Complete/reopen/verify/replay races and localized UI | +| M3 — Household supplies | Products, stock ledger, demand, purchase and receipt | End-to-end material and replenishment consistency | +| M4 — Automation and HA surface | One durable engine, simple/default and optional advanced editors, entities and response services across domains | Replay/restart/loop/partial-run cases plus disposable-HA contracts in both deployment targets | +| M5 — Integrated acceptance | Dashboard, responsive UX, access control, Stable/Edge packaging | Full CI Check; local Google Chrome dogfooding and recorded cleanup | + +The product is not considered first-release complete at M2 or M3. +Test, user documentation and failure recovery travel with each change. +No implementation begins on an invented branch: maintainers and the Action retain their installed lifecycle. +Release, merge and deployment require the existing maintainer flow and explicit authorization. +Future optional depth includes predictive consumption, workload recommendations, rich rewards and external calendars. diff --git a/docs/sdd-validation.md b/docs/sdd-validation.md new file mode 100644 index 0000000..2f96c0f --- /dev/null +++ b/docs/sdd-validation.md @@ -0,0 +1,70 @@ +# Validation evidence + +Audited 2026-10-29. This is documentation validation, not application acceptance. + +| Check | Result | Meaning | +|---|---|---| +| Original twenty-section headings | PASS — 11/11 | Exact comparison with the unchanged upstream template | +| Original draft format validator | PASS — 11/11 | Required headings, supported length and numeric budgets | +| Original consistency validator | PASS — 11/11 | Case IDs, per-area counts, reciprocal requirements and declared paths | +| Original prerequisite structure policy | PASS | Unchanged standard/template meet the required structure | +| Local document links | PASS | File links resolve; placeholders in the unchanged original template are excluded | +| Original SDK catalog validator | BLOCKED — 33 errors | Proposed capabilities have no implemented entrypoints, code or tests | +| Upstream policy provenance | PASS — 7/7 | Source-copy Git blob IDs match fetched upstream files | +| Copilot installation | Unchanged | No Copilot implementation, profile, workflow, template, guide or setup file was edited | +| Application tests / coverage | Not implemented | Planned acceptance cases are not executed tests | +| Real Chrome dogfooding | Not run | Requires an implemented identifiable artifact | +| Product readiness | Draft | Accepted owner choices are separate from outstanding engineering proof | + +## Per-SDD results + +| Capability | Requirements | Planned cases | Original format/consistency | +|---|---:|---:|---| +| platform-foundation | 6 | 20 | PASS | +| household-identity | 7 | 30 | PASS | +| household-tasks | 9 | 38 | PASS | +| recurrence-calendar | 8 | 37 | PASS | +| points-rewards | 6 | 44 | PASS | +| shopping-management | 7 | 21 | PASS | +| household-inventory | 8 | 35 | PASS | +| home-assistant-surface | 8 | 33 | PASS | +| application-experience | 6 | 26 | PASS | +| delivery-quality | 8 | 24 | PASS | +| household-automation | 9 | 45 | PASS | + +Totals: 82 normative requirements and 353 distinct planned cases across eleven SDDs. +The owner-confirmed automation scope adds one engine capability with 45 planned cases; the HA surface remains the adapter owner. + +## Catalog limitation + +The unchanged SDK validator requires nonempty entrypoints, code and tests arrays even when status is proposed. +Eleven proposed capabilities therefore produce 33 precise absent-evidence errors; no other catalog errors were returned. +The original renderer generated CATALOG.md as an ownership view, not a validation override. +No fake implementation paths, status changes, schema substitution, weakened checks or Copilot edits were used. +Automatic feature-gate readiness remains blocked until real supported prerequisites exist. + +## Reproduction and provenance + +Copilot revision: f5e5a4cf9a80248994469cd88ad55eecab5b95ca. +Original validateSddMarkdown, validateSddDraftConsistency, validateSddPrerequisiteDocuments and validateCatalog +functions were run from byte-verified source copies. TypeScript was transpiled in memory without editing policy source. +Case/path consistency was checked against the actual PR base-tree inventory at 8ee7e1a15e91c91b6204ca97e8808c3207dee008. +All twenty headings were independently compared with the unchanged original template. + +To reproduce, fetch the seven exact upstream files listed in the evidence JSON, verify Git blob hashes, +transpile TypeScript without changing policy, and invoke the named functions on the proposed documents and base inventory. +The standard and template are also unchanged copies. Tables, planned paths and acceptance counts are fully declared. +A local review runner cannot replace the Action's bundled authority. +[Raw results and source provenance](evidence/sdd-validation.json) include Git blob and SHA-256 hashes. + +## PR #3 check audit — 2026-10-29 + +The reviewed head was fa7adf1118b85e1588f0de7d71a77f47822b5000. The initial Copilot - Commit attempt failed in automatic progress assessment with assessment-invalid, published as agent.failed. Its log did not identify an application-test or SDD-format failure. Retrying the failed job succeeded on attempt 2, including Copilot / Verification, without source/configuration changes to Copilot. [Inspect the run](https://github.com/vypdev/domus/actions/runs/40774284194). + +Pull-request and branch-sync workflows passed for that head. Copilot / Review was neutral because draft review is disabled; it is not an approved-review result. A new documentation commit requires its own current-head checks and cannot inherit this audit as passing evidence. + +## Subsequent check evidence and upstream ownership + +A subsequent documentation head, ce2871b15508a1de53eaceca9bada001b31c25f2, failed progress assessment in both attempts with assessment-invalid exposed as agent.failed. The [second-attempt log](https://github.com/vypdev/domus/actions/runs/40787905127/job/123168549416) did not identify an application-test or SDD-format failure. Detailed sanitized evidence is recorded in [Copilot issue #774](https://github.com/vypdev/copilot/issues/774#issuecomment-6483788546); the separate deterministic proposed-catalog limitation is reported in [Copilot issue #777](https://github.com/vypdev/copilot/issues/777). No causal link between those two failures is asserted. + +The current local document validation does not make either historical run green or claim current-head GitHub acceptance. New documentation commits have independent checks. Copilot and its installed resources remain unchanged while their owners investigate. diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000..306b71f --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,66 @@ +# Intended household journey + +Domus is not implemented yet. This guide describes the first integrated release. + +Open Domus, sign in with your own Home Assistant account and use Dashboard, Tasks, Calendar, Shopping, +Inventory, Family or Settings. English and Spanish are supported. Your role controls permitted actions, +with backend checks applying even when a client presents an outdated button. + +During explicit setup, choose how administration maps from HA: all HA administrators by default, only the verified administrator completing setup, or an explicitly selected HA user. The default gives each proven HA administrator inherited Domus administration; ordinary users are not promoted by opening the app. An administrator configures household permission profiles and per-member exceptions. Known suspension or revoked authority still blocks access; changing a label or choosing another performer never changes the caller's permission. + +## Daily work + +Create a task with only a title, then optionally set category, priority, duration, assignment, materials, +schedule, recurrence and verification. Claim available work or inspect assignments. +When completing, name the actual performers. A task awaiting verification does not award points yet. +For tasks with materials, review the planned amounts, adjust them to actual usage and submit them with completion. An unused material can explicitly have zero usage. The task can instead be configured for separate recording. Insufficient stock keeps the work completed and the affected consumption pending regularization; the result shows which material lines posted and which need review without inventing negative stock. Reopening or rejecting verification does not automatically return consumed supplies. +Adults need no verification by default; restricted performers require authorized-adult approval unless an administrator has explicitly configured a permitted task override. Recording someone else's work does not change that performer's role. +Completing a recurring occurrence leaves its definition intact. Reopening retains history and reverses +awards with visible ledger entries. +If a prerequisite is reopened after dependent work was completed, that dependent keeps its completion and points. Domus marks the changed dependency for review and links the prerequisite; it does not reopen a chain of work automatically. + +Calendar labels scheduled work, deadlines and actual completion separately. Fixed schedules keep their anchor +when completed late; relative schedules count from the actual work-completion date even when approval comes later. +By default the next occurrence appears when work is recorded, while any required approval holds its points. An authorized task setting can wait to show the next occurrence until approval, preserving the same due date. +When a daylight-saving change makes a scheduled time nonexistent, Domus keeps that occurrence and moves it forward to the first valid local time. The calendar shows the intended time and its adjustment; a 02:30 task in a 02:00–03:00 gap appears at 03:00. +When autumn repeats a local time, the task executes once at the first appearance by default. A household setting may select the second appearance; preview shows the resolved offset and preserves existing work. +Use month/week/day/agenda and member/category/status/priority/type filters. +Missed occurrences remain visibly pending by default. A per-task policy can change how missed work is handled; explicitly skipping work retains a skipped record and awards no completion points. +Changing recurrence shows a preview of future changes. Only executions that have not started are updated; work underway and history remain. If someone starts a task after the preview, refresh the plan before applying it. Explicit exceptions and any overlaps remain visible for review. + +## Supplies and shopping + +Add products independently from package formats and locations. Receive physical quantities into their base unit. +Record consumption explicitly. A low-stock policy or missing task material creates an attributable shopping demand. +Scan a barcode with the camera or enter it manually. Domus searches local products first. If an administrator configures Internet product lookup, you may retrieve a candidate and review its source before importing it. External unavailability does not block local search or manual creation. +Manual additional requests remain additional unless you choose overlapping intent. +A purchase can be partially received. Inventory is updated only for confirmed receipts, once. +Free-text groceries need no tracked product. + +## Participation + +Family shows assignments, completed work, estimated effort and point history. +Work performed on Sunday belongs to Sunday's household week even if approved Monday. While approval is pending, its points are not spendable; approval updates the original week's earned total and credits the current balance. History shows work, approval and posting times separately. Weekly earned points are distinct from your remaining balance after rewards. +An administrator configures collaborative allocation in the application. The default divides one conserved total, but the household may choose equal shares rounded down or up, two-decimal shares, full points for every performer, or authorized manual amounts. For a 10-point task with three performers, the selected policy can produce 3/3/4, 3/3/3, 4/4/4, 3.33/3.33/3.33 or 10/10/10. The preview and ledger explain the base value, policy, each share and actual total. Changing policy does not rewrite past awards; corrections and reopening compensate the amounts actually awarded. +Rewards are optional and do not control access to normal household responsibilities. +If reopening reverses points already spent, the balance can become negative. The history explains the deficit, earned points offset it, and new redemptions remain unavailable until the balance recovers and covers the reward cost. Delivered rewards remain delivered. +If an approved reward has not been delivered and loses its backing points, it waits on a funding hold. Approval and reservation stay visible; delivery is blocked until sufficient credit exists or an authorized explicit resolution occurs. Recovering points does not itself mean the reward was physically delivered, and cancellation is an explicit action. + +## Clear state and recovery + +Loading does not mean zero records. A saved task with a pending HA update is still saved. +A conflict keeps your entered values; review the latest record before resubmitting. +If the server is unavailable, your unsaved screen draft is not falsely labeled as committed or queued for offline sync. +Use the operation/history link to inspect what succeeded and what remains. + +## Household automation + +Settings -> Automations offers a simple/default editor and optional advanced editor in the first release. Start from a typed trigger, conditions and actions; advanced mode adds branches, bounded repetition/parallel steps and durable waits. Both views save the same rule. If the simple form cannot represent advanced content, it shows a summary and opens the advanced editor rather than deleting fields. + +Preview explains why a condition matches and what would happen without performing the actions. Enabling a validated rule is explicit. Execution history shows each saved effect, pending wait and safe retry/cancel action. If a task was created but a later notification failed, the task remains created and the retry addresses the notification. External HA automations may call the same public Domus actions. +Disabling stops new executions and subsequent steps in queued, waiting or active runs. A step already executing atomically may finish and its result remains in history. The status identifies any outcomes still settling. Re-enabling allows future triggers without silently resuming those cancelled runs or undoing saved effects. + +## Channels and privacy + +Stable is production; Edge is experimental and has separate data, credentials and HA identities. +No AI or external catalog is required. External calendar/export functions remain off unless explicitly configured. diff --git a/specs/CATALOG.md b/specs/CATALOG.md new file mode 100644 index 0000000..a5353de --- /dev/null +++ b/specs/CATALOG.md @@ -0,0 +1,155 @@ +# Product capability specification catalog + +> Generated from [`catalog.json`](./catalog.json). Do not edit this table by hand. +> Run `pnpm run generate:specifications` after changing catalog metadata. + +This catalog answers which product contract owns a capability and where its +implementation, verification, workflow, and user-documentation evidence lives. +An **As-built baseline** records verified current behavior; it does not hide known +debt or convert unknown historic intent into a design decision. + +| Capability ID | Status | Scope | Primary SDD | Evidence | +|---|---|---|---|---| +| `platform-foundation` | Proposed | One local modular application serves the complete household product in both a Supervisor-managed App and standalone Docker from the first release. Home Assistant owns user authentication; Domus owns its business records. | [Local application platform and persistence](./platform-foundation.md) | 5 paths · 2026-10-29 | +| `household-identity` | Proposed | Each participating person uses their own Home Assistant account. Domus associates that verified user with one household member and applies explicit backend permissions independently of an optional person entity. | [Household members, Home Assistant identity and permissions](./household-identity.md) | 5 paths · 2026-10-29 | +| `household-tasks` | Proposed | Members create and perform household responsibilities with explicit assignments, actual performers and history. A recurring definition survives completion of each individual occurrence. | [Task definitions, occurrences and household execution](./household-tasks.md) | 5 paths · 2026-10-29 | +| `recurrence-calendar` | Proposed | A bounded scheduler turns task definitions into stable occurrences and a family calendar distinguishes planned start, deadline and actual completion. | [Recurrence engine and family calendar](./recurrence-calendar.md) | 5 paths · 2026-10-29 | +| `points-rewards` | Proposed | Task completion produces auditable point entries. Household-configurable collaboration policies determine each share and the actual award total; corrections preserve history and optional rewards never control basic participation. | [Auditable points, participation and optional rewards](./points-rewards.md) | 5 paths · 2026-10-29 | +| `shopping-management` | Proposed | Shopping combines manual intent, replenishment and task materials without losing provenance. Buying an item and physically receiving it are separate recorded facts. | [Shared shopping demand, purchases and receipt](./shopping-management.md) | 5 paths · 2026-10-29 | +| `household-inventory` | Proposed | The household knows what is available, where it is stored and what needs replenishment through a local product catalog and an immutable stock movement ledger. | [Product catalog, pantry stock and replenishment](./household-inventory.md) | 5 paths · 2026-10-29 | +| `home-assistant-surface` | Proposed | Domus exposes its household capabilities as native Home Assistant entities, services and events. The already integrated HA MCP consumes these surfaces; no gateway work or second MCP is included. | [Home Assistant entities, services and integration](./home-assistant-surface.md) | 5 paths · 2026-10-29 | +| `application-experience` | Proposed | A complete household interface serves all six domains from the first release with fast daily actions, responsive navigation and clear operation results, independently of entity dashboards and AI. | [Responsive application, household dashboard and navigation](./application-experience.md) | 5 paths · 2026-10-29 | +| `delivery-quality` | Proposed | Every implemented capability starts with meaningful tests and enforced architecture boundaries. A CI Check workflow validates each PR update, and both deployment targets ship isolated experimental and production channels. | [Clean Architecture, CI Check and isolated Stable and Edge channels](./delivery-quality.md) | 5 paths · 2026-10-29 | +| `household-automation` | Proposed | Simple/default and optional advanced editors share one durable declarative automation engine in the first release, invoking authorized household commands with replay-safe execution and visible traces. | [Household automation engine and simple/advanced rule editors](./household-automation.md) | 5 paths · 2026-10-29 | + +## Evidence map + +### `platform-foundation` — Local application platform and persistence + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/platform-foundation.md`](./platform-foundation.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `household-identity` — Household members, Home Assistant identity and permissions + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/household-identity.md`](./household-identity.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `household-tasks` — Task definitions, occurrences and household execution + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/household-tasks.md`](./household-tasks.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `recurrence-calendar` — Recurrence engine and family calendar + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/recurrence-calendar.md`](./recurrence-calendar.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `points-rewards` — Auditable points, participation and optional rewards + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/points-rewards.md`](./points-rewards.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `shopping-management` — Shared shopping demand, purchases and receipt + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/shopping-management.md`](./shopping-management.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `household-inventory` — Product catalog, pantry stock and replenishment + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/household-inventory.md`](./household-inventory.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `home-assistant-surface` — Home Assistant entities, services and integration + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/home-assistant-surface.md`](./home-assistant-surface.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `application-experience` — Responsive application, household dashboard and navigation + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/application-experience.md`](./application-experience.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `delivery-quality` — Clean Architecture, CI Check and isolated Stable and Edge channels + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/delivery-quality.md`](./delivery-quality.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +### `household-automation` — Household automation engine and simple/advanced rule editors + +- Owner: Domus maintainers (review assignment pending) +- Last verified: 2026-10-29 +- Specifications: [`specs/household-automation.md`](./household-automation.md) +- Workflows: Not applicable for this capability. +- Entrypoints: Not applicable for this capability. +- Core code: Not applicable for this capability. +- Tests: Not applicable for this capability. +- User documentation: [`docs/product-vision.md`](../docs/product-vision.md) · [`docs/architecture.md`](../docs/architecture.md) · [`docs/operations.md`](../docs/operations.md) · [`docs/user-guide.md`](../docs/user-guide.md) · [`docs/contracts/home-assistant.md`](../docs/contracts/home-assistant.md) + +## Maintenance contract + +1. Read the relevant SDD before changing a catalogued capability. +2. Change the SDD, catalog evidence, tests, and user documentation together when + behavior or an architecture boundary changes. +3. Use repository-relative paths in `catalog.json`; each path is validated and every + top-level product SDD must have exactly one capability owner. +4. Run `pnpm run validate:specifications` in local and CI validation. diff --git a/specs/README.md b/specs/README.md new file mode 100644 index 0000000..c8454ad --- /dev/null +++ b/specs/README.md @@ -0,0 +1,254 @@ +# Product Specification Standard + +This directory contains implementation-driving product and engineering +specifications. A spec is a shared product contract, not only a technical design. +It must make the intended behavior understandable to someone who did not take +part in the original discussion and testable by someone who did not implement it. + +New specifications start from [`_template.md`](./_template.md). Existing specs +should converge on this standard when they are materially revised. + +The capability inventory and its implementation evidence live in +[`catalog.json`](./catalog.json); [`CATALOG.md`](./CATALOG.md) is the generated +human-readable view. Run `pnpm run validate:specifications` after changing a +specification or any catalogued path, and `pnpm run generate:specifications` +after changing catalog metadata. + +### Retrospective (as-built) specifications + +An already implemented capability MAY be documented with status +`As-built baseline`. This is not a claim that the feature is perfect or that all +historic design choices were intentional. Its purpose is to establish a +reviewable contract before subsequent changes. + +An as-built baseline MUST: + +- label verified repository behavior as **observed behavior**; +- label the behavior maintainers choose to preserve as the **intentional + contract**; +- record defects, missing evidence, and architectural weaknesses under **known + debt and limitations**; +- mark historic motivation as **unknown** when evidence does not establish it; +- keep desired improvements separate from the current contract and link them to + follow-up work rather than presenting them as implemented; +- cite current code, workflows, tests, and user documentation; and +- use the same UX, architecture, configuration, security, testing, + documentation, acceptance, and Definition of Done standard as a prospective + specification. + +The baseline date and `Last verified` catalog date identify the repository +snapshot that was audited. A behavior-changing implementation MUST update the +relevant SDD, catalog evidence, tests, and user documentation in the same change. + +## 1. Core criteria + +Every spec must be: + +- **Product-near:** use the names, states, actions, and surfaces that users and + operators will actually see. +- **Visual where it helps:** show multi-step flows, state changes, ownership, or + several relationships with a compact diagram, table, timeline, or Markdown + wireframe. +- **Textually complete:** every visual has an adjacent textual equivalent; color, + emoji, screenshots, and Mermaid are never the only source of meaning. +- **Explicit:** distinguish current facts, proposed behavior, recommended + defaults, configurable choices, fixed safety limits, non-goals, and open + questions. +- **End-to-end:** include happy paths, alternatives, partial success, failure, + retry, cancellation, migration, and cleanup where relevant. +- **Verifiable:** important statements use normative language and map to an + automated test, contract check, or explicit human acceptance artifact. +- **Proportional:** a concern may be marked not applicable with a reason; it must + not disappear silently. + +Use `MUST`, `SHOULD`, and `MAY` deliberately. A `MUST` requires an acceptance +scenario. Avoid prescribing implementation details unless they protect product +behavior, architecture, interoperability, or safety. + +## 2. Required specification contract + +A specification must cover the following concerns or mark them not applicable: + +| Concern | Required outcome | +|---|---| +| Decision metadata | Status, date, owners, scope, review gates, and unresolved decisions | +| Problem and evidence | Current behavior, concrete pain, affected actors, and evidence/source | +| Goals and limits | Measurable outcomes, non-goals, fixed safety/product invariants | +| Product journey | Current versus proposed flow, actors, entrypoints, visible surfaces, next actions | +| Domain model | Shared terminology, invariants, states, transitions, and ownership of facts | +| Configuration | Recommended defaults, bounded alternatives, validation, precedence, persistence, migration | +| Architecture | Dependency direction, pure policy, use cases, ports, adapters, presentation, state and trust boundaries | +| UI/UX and content | Information hierarchy, examples for every primary state, navigation, accessibility, localization | +| Failure and recovery | Impact, partial-success facts, retryability, idempotency, cleanup, operator action | +| Security and privacy | Permissions, untrusted input, secrets, execution boundaries, auditability | +| Observability | User status, operator evidence, logs/metrics, correlation, noise budget | +| Compatibility and rollout | Existing in-flight state, migration, deprecation, rollout and rollback | +| Testing | Numeric risk-derived budget, distribution, coverage, fixtures, integration and human evidence | +| Documentation | User, setup, configuration, recovery, migration, architecture and discoverability | +| Acceptance and DoD | Observable scenarios, traceability, implementation order, all quality gates | + +## 3. Product and GitHub UI/UX standard + +GitHub issues, pull requests, reviews, comments, checks, labels, releases, and Job +Summaries are product surfaces when a person uses them to understand or operate a +feature. CLI output and generated documentation are product surfaces for the same +reason. + +For each primary state, the first visible content must answer in this order: + +1. What is happening now? +2. What completed already? +3. What happens next? +4. Is human action required? +5. What is the impact, especially for partial success or failure? +6. Where can the result or transition be inspected? +7. Where are technical details available? + +A spec affecting these surfaces must include representative rendered Markdown +or a wireframe for at least pending, action-required, blocked/failed, partially +complete, and complete states. Use actual product terminology and plausible data. +Do not specify only abstract fields such as `status`, `message`, and `url`. + +The UX contract must define, when applicable: + +- one primary status and one primary action; +- progress/state representation and the facts behind it; +- deterministic titles, headings, labels, and durable markers; +- descriptive links to the issue, PR, comparison, commit, run, artifact, release, + package, documentation, and recovery action; +- progressive disclosure: user meaning first, technical diagnostics later; +- error content in `impact -> cause -> action -> retained state` order; +- idempotent update behavior and a bounded comment/notification budget; +- locale source, supported locales, and fallback behavior; +- narrow/mobile readability, light/dark themes, and logical heading/table use; +- sanitization of mentions, commands, Markdown, HTML markers, URLs, and diagrams; + and +- a textual fallback for Mermaid, images, icons, and other visual elements. + +For a flow with three or more dependent transitions, include one overview visual. +For a user-facing issue or PR change, include at least one concrete content +mockup. Screenshots can supplement these artifacts but cannot replace the +semantic written contract. + +## 4. Clean Architecture standard + +Apply Clean Architecture to the repository's real boundaries rather than +inventing a parallel folder taxonomy. A design must identify: + +- domain entities, value objects, invariants, and pure policies; +- application use cases and narrow immutable input/output contracts; +- semantic ports that express capabilities without provider DTOs; +- data/provider adapters and their error mappings; +- infrastructure and composition ownership; +- entrypoint responsibility and trusted/untrusted event boundaries; +- presentation view models and renderers, separate from mutation policy; +- durable state, concurrency, idempotency, and migration ownership; and +- forbidden dependency directions that can be enforced automatically. + +Use a component/dependency diagram when three or more layers or external systems +interact. Use a sequence or state diagram when ordering, retries, asynchronous +events, or partial completion affect correctness. + +Architecture requirements are incomplete without executable constraints. The +spec must state which dependency, contract, cycle, schema, or workflow checks +will prevent boundary erosion. + +## 5. Configuration standard + +Configuration exists to support legitimate product variation, not to make every +implementation detail optional. Every input must define: + +| Field | Required information | +|---|---| +| Name and type | Stable public name, type, and owning surface | +| Recommended default | Safe default and why it is recommended | +| Allowed values/range | Bounded choices with observable semantics | +| Validation | Invalid values and invalid cross-field combinations | +| Scope and precedence | Project/repository/operation scope and override order | +| Persistence | Whether an in-flight operation snapshots or rereads the value | +| Migration | Behavior for absent, retired, renamed, or future values | +| Security | Values that must never accept arbitrary code, refs, URLs, or secrets | + +Show at least one recommended configuration and one meaningful alternative. +State which correctness and safety invariants are intentionally not configurable. + +## 6. Test budget standard + +Every implementation-driving spec must contain a numeric test budget. Derive it +from the behavior and risk inventory; do not reuse one universal count for small +and large changes. + +The budget table must distribute a minimum number of distinct cases across the +applicable areas: + +- domain/configuration/pure planning; +- state transitions, idempotency, replay, cancellation, and races; +- application use cases; +- adapters and provider error mapping; +- workflows, permissions, schemas, and setup contracts; +- presentation states, links, localization, accessibility, and sanitization; +- integration/end-to-end and compatibility/migration; and +- security/abuse cases. + +Each `it`/`test` case counts once. Parameterized rows count separately only when +they represent distinct behavior. The number is a floor, not a substitute for +covering every requirement and failure mode. + +The spec must also define: + +- repository-wide thresholds that remain in force; +- higher branch coverage for new pure policy where justified; +- changed-module expectations; +- deterministic fakes instead of real waits or live services; +- fixtures/golden output without relying only on snapshots; +- workflow/contract checks that parse structure rather than grep prose; +- required manual UX evidence that automation cannot establish; and +- a traceability mapping from each normative requirement to tests or evidence. + +## 7. Documentation standard + +Documentation is an implementation deliverable. Identify the applicable +audiences and artifacts: + +- user journey and recommended default; +- setup, permissions, environments, credentials, and external prerequisites; +- complete configuration reference and examples; +- operator state model, troubleshooting, recovery, replay, and cleanup; +- upgrade, migration, compatibility, deprecation, and rollback; +- architecture, contracts, trust boundaries, and contributor guidance; and +- route/navigation registration, links, assets, examples, and validation jobs. + +Lead documentation with the normal path and one helpful visual, then disclose +configuration, failures, and internals progressively. Examples must be checked +against implementation fixtures or contract tests whenever practical. + +## 8. Acceptance, traceability, and review + +Acceptance scenarios describe observable behavior, not implementation activity. +Cover normal, alternative, boundary, invalid, duplicate, out-of-order, partial, +failure, recovery, migration, security, UX, and accessibility behavior as +applicable. + +Maintain a traceability table for substantial specs: + +```text +Requirement -> domain/policy/use case/adapter/presentation -> test or evidence -> documentation +``` + +Before changing a spec to `Ready for implementation`, reviewers must be able to +answer yes to the following: + +- Is the origin/current behavior supported by evidence? +- Can a user understand the proposed product without reading implementation code? +- Are product defaults and non-configurable safety limits explicit? +- Are architecture boundaries and executable constraints clear? +- Is the numeric test budget proportional and complete? +- Are documentation and migration deliverables named? +- Do UI examples cover pending, action, error/partial, and completed states? +- Can status and required action be understood quickly without logs? +- Are security, idempotency, retries, concurrency, and cleanup addressed? +- Does every `MUST` map to acceptance and verification? +- Are material decisions resolved or explicitly blocking readiness? + +The Definition of Done must repeat these gates. A concern mentioned only in an +introductory paragraph is not an enforceable delivery requirement. diff --git a/specs/_template.md b/specs/_template.md new file mode 100644 index 0000000..74c3fe2 --- /dev/null +++ b/specs/_template.md @@ -0,0 +1,356 @@ +# + +- Status: Draft +- Date: YYYY-MM-DD +- Catalog capability ID: +- Last verified: +- Owners: +- Scope: +- Related issues/PRs: +- Required review gates: product UX, architecture, testing, documentation, + security/operations +- Open decisions blocking readiness: + +> Start with the repository standard in [`README.md`](./README.md). Remove this +> note when the spec is ready. Mark a non-applicable section explicitly and give +> a reason instead of silently deleting the concern. + +## 1. Executive summary + +Describe the user-visible outcome, the recommended default, and the principal +safety/correctness rule in plain language. + +```text + +``` + +## 2. Problem, current behavior, and evidence + +### 2.1 Problem + +Who is affected, what they cannot understand/do safely, and why it matters. + +### 2.2 Current behavior + +Number the actual current sequence. Separate verified facts from assumptions. + +### 2.3 Evidence + +- Code/workflow/documentation references: +- Incidents or concrete examples: +- External primary sources: +- Unknowns: + +### 2.4 Retrospective classification (as-built baselines only) + +- Observed behavior: +- Intentional contract: +- Known debt and limitations: +- Unknown rationale: +- Proposed improvements: + +For a prospective specification, mark this subsection not applicable because no +implemented baseline is being reconstructed. + +## 3. Actors, surfaces, and terminology + +| Actor | Goal | Entry point | Visible surfaces | +|---|---|---|---| +| | | | | + +Define product terms, branch/data roles, ownership of facts, and language that +must remain consistent across UI, code, tests, and documentation. + +## 4. Goals, non-goals, and fixed invariants + +### 4.1 Goals + +1. + +### 4.2 Non-goals + +1. + +### 4.3 Fixed product/safety invariants + +1. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| | | | | + +For three or more dependent transitions, add a visual and a textual equivalent: + +```mermaid +flowchart LR + A[User entry point] --> B[System transition] + B --> C[Visible result] +``` + +Text equivalent: ` -> -> `. + +## 6. Functional behavior and state model + +### 6.1 Happy path + +1. + +### 6.2 Alternative paths + +- + +### 6.3 State machine + +| State | Entered when | User-visible meaning | Allowed next states | Recovery/owner | +|---|---|---|---|---| +| | | | | | + +Define duplicate, stale, out-of-order, canceled, and partially completed event +behavior where applicable. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `` | | `` — | | | + +Document: + +- validation and invalid cross-field combinations; +- precedence and operation-time snapshot/reread behavior; +- migration, retired, unknown, and deprecated values; +- one recommended example and one meaningful alternative; and +- behavior intentionally not configurable. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +| Layer/boundary | Owns | Must not own/import | +|---|---|---| +| Domain/pure policy | | | +| Application | | | +| Adapters/data | | | +| Infrastructure/composition | | | +| Entrypoints | | | +| Presentation | | | + +```mermaid +flowchart LR + E[Entrypoint] --> A[Application use case] + A --> D[Domain policy] + A --> P[Semantic port] + I[Provider adapter] --> P + A --> V[Presentation model] +``` + +### 8.2 Contracts, state, and trust boundaries + +- Pure decisions: +- Application contracts: +- Semantic ports: +- Durable state/schema ownership: +- Concurrency/idempotency strategy: +- Trusted and untrusted inputs: +- Provider error mapping: + +### 8.3 Executable architecture constraints + +- + +## 9. UI/UX and content contract + +Treat issues, PRs, comments, labels, checks, summaries, CLI output, and docs as UI +when applicable. + +### 9.1 Information hierarchy + +1. Current status +2. Completed facts +3. Next transition +4. Human action, or explicit statement that none is needed +5. Impact and inspectable links +6. Collapsed technical evidence + +### 9.2 Representative primary view + +```markdown + + +# + +> **Current status:** +> +> **Action required:** + +## Progress + +- [x] +- [ ] + +## What happens next + + + +## Links + +[Descriptive destination](...) · [Descriptive destination](...) + +
+Technical details + +
+``` + +Add concrete variants for: + +- pending/no action; +- action required; +- blocked or failed before irreversible effects; +- partially successful after an irreversible effect; and +- completed. + +### 9.3 Issue, PR, and comment behavior + +- Deterministic titles and purpose: +- What merge/close/retry will do: +- Durable marker and idempotent update policy: +- Comment/notification budget: +- Labels and checks as supplemental state: +- Direct links and navigation: + +### 9.4 Accessibility, localization, and responsive behavior + +- Supported locales and fallback: +- Textual equivalent for visuals: +- Narrow/mobile and light/dark expectations: +- Heading/table/link rules: +- Sanitization of untrusted Markdown, mentions, commands, markers, and URLs: + +## 10. Failure, recovery, and cleanup + +| Failure/partial state | User impact | Retained facts | Automatic retry | Required action | Cleanup | +|---|---|---|---|---|---| +| | | | | | | + +User-facing errors follow `impact -> cause -> action -> retained state` and must +not imply that an already successful irreversible action failed. + +## 11. Security, permissions, and privacy + +1. +2. +3. +4. + +## 12. Observability and operational UX + +- User-facing state: +- Job Summary/operator evidence: +- Logs, metrics, and correlation: +- Pending external dependency versus workflow failure: +- Rate-limit/retry behavior: +- Noise/comment budget: + +## 13. Compatibility, migration, rollout, and rollback + +- Existing in-flight operations/data: +- Schema/configuration migration: +- Deprecated behavior and compatibility window: +- Rollout stages/feature flag if needed: +- Rollback and irreversible effects: + +## 14. Testing strategy and numeric budget + +The count is derived from the behavior/risk inventory and is a minimum, not a +substitute for requirement coverage. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain/configuration/pure planning | | | +| State/application/idempotency/races | | | +| Adapters/provider contracts | | | +| Workflows/setup/schema | | | +| UI/UX/localization/sanitization | | | +| Integration/security/migration | | | +| **Total** | **** | No double counting | + +Define: + +- repository and changed-module coverage thresholds; +- pure-policy branch coverage; +- table-driven, replay, race, adapter, workflow-contract, and security tests; +- deterministic clocks/IDs/fakes with no real waits or live services; +- golden UI fixtures plus semantic assertions; and +- manual UX evidence for readability that automation cannot establish. + +## 15. Documentation and discoverability + +| Audience | Artifact/page | Required content | Validation/navigation | +|---|---|---|---| +| User | | | | +| Setup owner | | | | +| Operator | | | | +| Contributor | | | | + +Include migration and troubleshooting documentation where applicable. Keep +examples synchronized with implementation fixtures or contract tests. + +## 16. Acceptance scenarios + +1. Given ``, when ``, then ``. +2. +3. +4. +5. +6. +7. +8. + +## 17. Requirements traceability + +| Requirement | Policy/use case/adapter/presentation | Test or evidence | Documentation | +|---|---|---|---| +| `
` | | | | + +## 18. Implementation sequence + +1. Contracts, decisions, configuration, and architecture checks. +2. Pure policies and tests. +3. State/application orchestration and tests. +4. Adapters/workflows and contract tests. +5. Presentation, fixtures, accessibility, and localization. +6. Migration, recovery, security, documentation, and generated artifacts. +7. Integration, coverage, human UX evidence, and final validation. + +Adjust ordering to risk and dependencies; do not postpone documentation or UX +until after behavior is considered complete. + +For an as-built baseline, interpret this as the required change sequence for +future maintenance and state explicitly that the document itself proposes no +behavior change. + +## 19. Definition of Done + +- [ ] Every normative requirement has acceptance and traceability. +- [ ] Architecture boundaries are implemented and automatically enforced. +- [ ] Numeric test budget, distribution, and coverage requirements pass. +- [ ] Configuration defaults, limits, validation, persistence, and migration agree. +- [ ] Primary UI states and content examples are implemented and reviewed. +- [ ] Accessibility, localization, responsive behavior, sanitization, and noise + budgets pass. +- [ ] User/setup/operator/contributor documentation is complete and discoverable. +- [ ] Failure, partial success, retry, idempotency, security, and cleanup pass. +- [ ] Required generated artifacts and repository validation commands pass. +- [ ] `specs/catalog.json` evidence and `specs/CATALOG.md` are current and + `pnpm run validate:specifications` passes. +- [ ] No readiness-blocking decision remains unresolved. + +## 20. References and decisions + +- Primary sources: +- Related specs/ADRs/issues/PRs: +- Decisions and rejected alternatives: +- Follow-up work explicitly outside this spec: diff --git a/specs/application-experience.md b/specs/application-experience.md new file mode 100644 index 0000000..e092ab1 --- /dev/null +++ b/specs/application-experience.md @@ -0,0 +1,295 @@ +# Responsive application, household dashboard and navigation + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: application-experience +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: A complete household interface serves all six domains from the first release with fast daily actions, responsive navigation and clear operation results, independently of entity dashboards and AI. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed design system review; real mobile/companion and public host-context evidence; accessibility acceptance. The owner selected Lit/TypeScript/Vite, HA-coherent owned components, Storybook and Playwright on 2026-10-29. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +A complete household interface serves all six domains from the first release with fast daily actions, responsive navigation and clear operation results, independently of entity dashboards and AI. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +Household members need coherent task, calendar, shopping, inventory and participation workflows rather than a loose collection of HA entity cards. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Authenticated household member; restricted member; administrator; keyboard and screen-reader users. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| application-experience-R1 | The application MUST provide complete navigation and first-release workflows across tasks, calendar, shopping, inventory, family and settings. | +| application-experience-R2 | The dashboard MUST prioritize actionable household information with distinct freshness and no invented zero values during failed reads. | +| application-experience-R3 | Commands MUST show pending, action-required, failed, partial and completed outcomes and preserve unsaved input on recoverable errors. | +| application-experience-R4 | The UI MUST support mobile, tablet, desktop, keyboard navigation, accessible names/focus and light/dark themes. | +| application-experience-R5 | English and Spanish localization MUST use stable keys and safe English fallback without localizing public service identifiers. | +| application-experience-R6 | The UI MUST use backend permissions and validated transports, remain useful without AI, isolate Lit presentation primitives from application/API logic, and reject private HA modules, parent-DOM/private-storage access and untrusted host messages as sources of authority. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +Routes: Dashboard, Tasks, Calendar, Shopping, Inventory, Family and Settings. A view model owns loading, data freshness, empty, validation, authorization, conflict, pending and partial states. Dashboard prioritizes today's tasks, overdue, my tasks, unclaimed work, shopping requirements, low stock, upcoming expirations/maintenance, recent completion, weekly points and participation. Optional recommendations are explicitly labeled and never silently execute. Displayed capabilities derive from backend permissions, which remain authoritative. + +Explicit setup presents the three administrator-mapping modes with all HA administrators selected by default, while the backend proves setup authority. Settings exposes household permission profiles and per-member exceptions to authorized administrators, with effective-grant provenance and current policy revisions. Controls follow effective permissions rather than assuming a role label alone fixes every grant. A missing identity/administrator proof is a blocked setup state, not a reason to trust host UI hints or choose a weaker mapping silently. + +### 6.2 States and alternatives + +View idle -> loading -> ready/empty/error. Command draft -> validating -> submitting -> saved/pending/partial/conflict/denied. The client retains form data on a failure or conflict. A local server outage is not an offline-write queue; pending drafts remain visible without falsely claiming saved work. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `theme` | enum | auto | light, dark or auto | member preference; persisted | +| `locale` | enum | browser language | en, es; base-language match then en | member preference; persisted | +| `dashboard_member_filter` | member reference | current member | authorized member or household view | member preference | +| `reduced_motion` | preference | system setting | respect reduced-motion; no essential animated-only information | browser; no server override | + +These are proposed defaults pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: keep the defaults above. Meaningful alternative: a member selects Spanish and dark theme while the same household policies remain in force. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +The owner selected Lit/TypeScript with Vite on 2026-10-29 after comparing Gateway and Symphonia. Domus owns reusable HA-coherent presentation primitives and semantic design tokens, cataloged in Storybook and exercised through Playwright. Presentation components call application controllers through a typed DomusPort; an HTTP adapter validates DTOs. Views do not calculate permissions, recurrence, stock consolidation or point awards. Relative URLs and deployment-aware base paths support Ingress and standalone. No private HA frontend bundles, parent DOM or private host storage are accessed. React is not the selected stack. + +HA's outer shell owns host navigation; Domus owns interior routes and content. A public host-context adapter validates message source, origin, shape and bounds, treating all accepted fields as presentation hints only. It does not assume HA user theme, locale, timezone or authentication is forwarded to an App iframe. Explicit member preferences and deterministic browser fallbacks remain usable without host hints. Host-managed safe-area padding is applied once; a full-bleed opt-in requires supported-version evidence. Vite relative assets alone do not establish deep-route reload or Ingress compatibility, so those behaviors have explicit browser cases. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Loading your household. No action required. | +| Action required | Choose who completed this task. Your other entries are retained. | +| Blocked | The household server is unavailable. Your draft is retained in this screen. Retry when it reconnects. | +| Partial | Your purchase was saved. Stock receipt needs attention. Open the receipt. | +| Complete | All six domains are available. Today's next action: complete “Clean the bathrooms”. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 26 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| UI and accessibility | 14 | first-release membership permissions; a viewer account; overdue and decorative statistics | +| Integration and recovery | 2 | a maintenance task lacking a material; inventory read failure | +| State and concurrency | 1 | a command in progress | +| Deployment and contracts | 5 | localized navigation; an Ingress prefix or standalone base path | +| Security and privacy | 4 | direct backend denial after a role change; hostile task text and no AI service | +| **Total** | **26** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| application-experience-C01 | UI and accessibility | application-experience-R1 | Given first-release membership permissions, a user can navigate all domain routes and return to the previous filter state. | +| application-experience-C02 | Integration and recovery | application-experience-R1 | Given a maintenance task lacking a material, the user can inspect the linked inventory shortfall and shopping demand. | +| application-experience-C03 | UI and accessibility | application-experience-R1 | Given a default viewer account without mutation exceptions, visible controls reflect read-only access while routes remain understandable. | +| application-experience-C04 | UI and accessibility | application-experience-R2 | Given overdue and decorative statistics, the dashboard presents actionable tasks before summary charts. | +| application-experience-C05 | Integration and recovery | application-experience-R2 | Given inventory read failure, the dashboard shows unavailable stock facts rather than zero low-stock products. | +| application-experience-C06 | UI and accessibility | application-experience-R2 | Given an empty new household, the dashboard offers authorized setup actions without false completed statistics. | +| application-experience-C07 | State and concurrency | application-experience-R3 | Given a command in progress, repeated clicks reuse its operation key and show one pending result. | +| application-experience-C08 | UI and accessibility | application-experience-R3 | Given a conflict, entered form fields are retained while the user reviews the newer revision. | +| application-experience-C09 | UI and accessibility | application-experience-R3 | Given a saved receipt and failed stock post, the view names both retained success and the remaining action. | +| application-experience-C10 | UI and accessibility | application-experience-R4 | Given a 360-pixel viewport, primary actions and labels remain readable without page-level horizontal scrolling. | +| application-experience-C11 | UI and accessibility | application-experience-R4 | Given keyboard-only use, a modal manages focus and returns it to the triggering control. | +| application-experience-C12 | UI and accessibility | application-experience-R4 | Given dark theme and reduced motion, contrast, focus and non-animated state announcements remain usable. | +| application-experience-C13 | UI and accessibility | application-experience-R5 | Given an es-MX browser language, the Spanish base catalog is used. | +| application-experience-C14 | UI and accessibility | application-experience-R5 | Given a missing or invalid translation key, safe English copy appears without leaking raw markup. | +| application-experience-C15 | Deployment and contracts | application-experience-R5 | Given localized navigation, domus.complete_task remains the same public service identifier. | +| application-experience-C16 | Security and privacy | application-experience-R6 | Given direct backend denial after a role change, the view explains the denial without relying on hidden buttons. | +| application-experience-C17 | Deployment and contracts | application-experience-R6 | Given an Ingress prefix or standalone base path, assets and API requests resolve through their respective public roots. | +| application-experience-C18 | Security and privacy | application-experience-R6 | Given hostile task text and no AI service, rendering stays inert and ordinary task completion still works. | +| application-experience-C19 | Security and privacy | application-experience-R6 | Given a host-context message with a wrong source/origin or malformed fields, the adapter rejects it without changing authenticated identity, role or trusted UI context. | +| application-experience-C20 | Deployment and contracts | application-experience-R6 | Given a private HA module import or parent-DOM/private-storage lookup in presentation source, the executable boundary check rejects it. | +| application-experience-C21 | UI and accessibility | application-experience-R5 | Given absent public HA locale/theme hints, explicit member preferences then documented browser/English fallbacks render a usable UI without reading host internals. | +| application-experience-C22 | UI and accessibility | application-experience-R4 | Given a narrow Ingress iframe with host-managed safe-area padding, the UI applies insets once and keeps focused fields and actions visible with the virtual keyboard. | +| application-experience-C23 | Deployment and contracts | application-experience-R6 | Given a Storybook presentation primitive importing an API adapter or domain command, architecture validation rejects the component while pure presentation fixtures build independently. | +| application-experience-C24 | Deployment and contracts | application-experience-R6 | Given a direct reload of an interior route under a non-root Ingress prefix, the authenticated page, assets, API and any push transport resolve within the validated deployment base. | +| application-experience-C25 | UI and accessibility | application-experience-R6 | Given an authorized administrator editing a profile/member exception, the UI exposes the effective grant source and retained policy revision, and a later backend revocation updates controls without losing a denied user's draft. | +| application-experience-C26 | Security and privacy | application-experience-R6 | Given explicit setup, all three mapping modes are available with all_ha_administrators as default; failed proof of setup authority blocks saving and no browser/host field silently grants administration. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/application-experience.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| application-experience-R1 | application-experience-C01, application-experience-C02, application-experience-C03 | +| application-experience-R2 | application-experience-C04, application-experience-C05, application-experience-C06 | +| application-experience-R3 | application-experience-C07, application-experience-C08, application-experience-C09 | +| application-experience-R4 | application-experience-C10, application-experience-C11, application-experience-C12, application-experience-C22 | +| application-experience-R5 | application-experience-C13, application-experience-C14, application-experience-C15, application-experience-C21 | +| application-experience-R6 | application-experience-C16, application-experience-C17, application-experience-C18, application-experience-C19, application-experience-C20, application-experience-C23, application-experience-C24, application-experience-C25, application-experience-C26 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/catalog.json b/specs/catalog.json new file mode 100644 index 0000000..aa3d450 --- /dev/null +++ b/specs/catalog.json @@ -0,0 +1,313 @@ +{ + "version": 1, + "capabilities": [ + { + "id": "platform-foundation", + "title": "Local application platform and persistence", + "status": "proposed", + "scope": "One local modular application serves the complete household product in both a Supervisor-managed App and standalone Docker from the first release. Home Assistant owns user authentication; Domus owns its business records.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/platform-foundation.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Storage concurrency verification; supported Home Assistant release matrix; backup retention and restore targets. The owner selected Python/FastAPI, SQLite, one household per installation and a thin HA integration on 2026-10-29.", + "copilotChangesAllowed": false + } + }, + { + "id": "household-identity", + "title": "Household members, Home Assistant identity and permissions", + "status": "proposed", + "scope": "Each participating person uses their own Home Assistant account. Domus associates that verified user with one household member and applies explicit backend permissions independently of an optional person entity.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/household-identity.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed permission matrix/override review; authenticated recovery after external HA account loss; proof of HA identity/administrator status in both deployment targets; technical service principal policy. The owner confirmed three administrator-mapping modes with all HA administrators as the default, plus configurable household profiles and per-member permission exceptions.", + "copilotChangesAllowed": false + } + }, + { + "id": "household-tasks", + "title": "Task definitions, occurrences and household execution", + "status": "proposed", + "scope": "Members create and perform household responsibilities with explicit assignments, actual performers and history. A recurring definition survives completion of each individual occurrence.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/household-tasks.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed role/override review; first-release advanced task-type matrix. The owner confirmed role-default verification, material-completion handling and preservation of completed downstream work/points when its prerequisite is reopened on 2026-10-29.", + "copilotChangesAllowed": false + } + }, + { + "id": "recurrence-calendar", + "title": "Recurrence engine and family calendar", + "status": "proposed", + "scope": "A bounded scheduler turns task definitions into stable occurrences and a family calendar distinguishes planned start, deadline and actual completion.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/recurrence-calendar.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Supported RRULE subset, time-zone/gap/fold library interoperability and calendar projection review. The owner confirmed first-instant execution for repeated local times with a household-configurable second-instant option, alongside gap advancement, actual-completion anchoring, successor/missed-work defaults and previewed future rule edits.", + "copilotChangesAllowed": false + } + }, + { + "id": "points-rewards", + "title": "Auditable points, participation and optional rewards", + "status": "proposed", + "scope": "Task completion produces auditable point entries. Household-configurable collaboration policies determine each share and the actual award total; corrections preserve history and optional rewards never control basic participation.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/points-rewards.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed remainder/override review; child-facing review. The owner confirmed configurable allocation, role-default verification, actual-work reporting, factual negative balances and a funding hold on approved/unfulfilled redemptions without sufficient backing after reversal.", + "copilotChangesAllowed": false + } + }, + { + "id": "shopping-management", + "title": "Shared shopping demand, purchases and receipt", + "status": "proposed", + "scope": "Shopping combines manual intent, replenishment and task materials without losing provenance. Buying an item and physically receiving it are separate recorded facts.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/shopping-management.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed demand-coverage and unit fixtures; partial-receipt UX; price/currency precision; launch purchase-session scope. The owner confirmed manual-extra and duplicate-safe automatic consolidation defaults on 2026-10-29.", + "copilotChangesAllowed": false + } + }, + { + "id": "household-inventory", + "title": "Product catalog, pantry stock and replenishment", + "status": "proposed", + "scope": "The household knows what is available, where it is stored and what needs replenishment through a local product catalog and an immutable stock movement ledger.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/household-inventory.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Unit/package policy; reservation/replenishment review; barcode library/device evidence; external lookup provider feasibility, terms and response contract. The owner confirmed barcode scope, adjustable material recording and pending regularization rather than negative stock for task material shortfalls on 2026-10-29.", + "copilotChangesAllowed": false + } + }, + { + "id": "home-assistant-surface", + "title": "Home Assistant entities, services and integration", + "status": "proposed", + "scope": "Domus exposes its household capabilities as native Home Assistant entities, services and events. The already integrated HA MCP consumes these surfaces; no gateway work or second MCP is included.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/home-assistant-surface.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Public service schemas and scope review; technical principal authorization; response-service exposure contract; supported HA matrix.", + "copilotChangesAllowed": false + } + }, + { + "id": "application-experience", + "title": "Responsive application, household dashboard and navigation", + "status": "proposed", + "scope": "A complete household interface serves all six domains from the first release with fast daily actions, responsive navigation and clear operation results, independently of entity dashboards and AI.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/application-experience.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed design system review; real mobile/companion and public host-context evidence; accessibility acceptance. The owner selected Lit/TypeScript/Vite, HA-coherent owned components, Storybook and Playwright on 2026-10-29.", + "copilotChangesAllowed": false + } + }, + { + "id": "delivery-quality", + "title": "Clean Architecture, CI Check and isolated Stable and Edge channels", + "status": "proposed", + "scope": "Every implemented capability starts with meaningful tests and enforced architecture boundaries. A CI Check workflow validates each PR update, and both deployment targets ship isolated experimental and production channels.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/delivery-quality.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Runner/toolchain review; required-check configuration by maintainer; channel IDs and integration coexistence review; release publication authorization.", + "copilotChangesAllowed": false + } + }, + { + "id": "household-automation", + "title": "Household automation engine and simple/advanced rule editors", + "status": "proposed", + "scope": "Simple/default and optional advanced editors share one durable declarative automation engine in the first release, invoking authorized household commands with replay-safe execution and visible traces.", + "owner": "Domus maintainers (review assignment pending)", + "lastVerified": "2026-10-29", + "specs": [ + "specs/household-automation.md" + ], + "workflows": [], + "entrypoints": [], + "code": [], + "tests": [], + "documentation": [ + "docs/product-vision.md", + "docs/architecture.md", + "docs/operations.md", + "docs/user-guide.md", + "docs/contracts/home-assistant.md" + ], + "readiness": { + "state": "draft", + "implementationEvidence": "absent", + "blockingDecisions": "Detailed DSL/action catalog, numeric resource limits, external-effect receipts and supported HA/browser evidence. The owner confirmed both editors, one engine and disablement that stops new runs/later steps while retaining already-started atomic commands and effects.", + "copilotChangesAllowed": false + } + } + ] +} diff --git a/specs/delivery-quality.md b/specs/delivery-quality.md new file mode 100644 index 0000000..30164b1 --- /dev/null +++ b/specs/delivery-quality.md @@ -0,0 +1,295 @@ +# Clean Architecture, CI Check and isolated Stable and Edge channels + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: delivery-quality +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Every implemented capability starts with meaningful tests and enforced architecture boundaries. A CI Check workflow validates each PR update, and both deployment targets ship isolated experimental and production channels. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Runner/toolchain review; required-check configuration by maintainer; channel IDs and integration coexistence review; release publication authorization. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Every implemented capability starts with meaningful tests and enforced architecture boundaries. A CI Check workflow validates each PR update, and both deployment targets ship isolated experimental and production channels. + +```text +PR update -> CI Check -> reviewed artifact -> authorized channel publication +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +The owner requires full quality gates from the first code and explicit Stable/Edge channels analogous to the existing gateway, while prohibiting changes to Copilot. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Contributor; reviewer; release maintainer; local dogfooding operator. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| delivery-quality-R1 | Every first-party implementation MUST include meaningful tests from its first change and meet 100% available line, statement, function and branch coverage metrics without broad exclusions. | +| delivery-quality-R2 | Clean Architecture MUST be enforced by executable dependency, cycle and port-contract checks for backend, frontend and HA integration. | +| delivery-quality-R3 | A workflow named CI Check MUST run the full applicable suite for every PR head update, without path-based omissions, and publish a failing aggregate if any required job fails, skips unexpectedly or is cancelled. | +| delivery-quality-R4 | Stable and Edge MUST be available for both deployment targets with isolated data, credentials, identifiers and configured endpoints. | +| delivery-quality-R5 | Channel artifacts MUST identify immutable source and image digest, with tested migration/backup compatibility and no automatic production promotion. | +| delivery-quality-R6 | Google Chrome dogfooding MUST use the authorized local HA instance with identifiable test data, exact artifact evidence and explicit cleanup that preserves household production data. | +| delivery-quality-R7 | Tests and diagnostics MUST use bounded deterministic fakes in CI and redact secrets from artifacts while distinguishing browser evidence from unit coverage. | +| delivery-quality-R8 | Copilot MUST remain unchanged; application CI and channel work cannot edit its workflows, profiles, guidance, templates or implementation, with only the owner's narrow dependency-setup exception. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +VerificationRun records exact commit, tests, coverage, architecture checks and artifacts. ChannelManifest records stable or edge, version, source SHA, image digest, compatible schema and HA surface namespace. Proposed Supervisor slugs domus and domus_edge, isolated data/credentials, and distinct standalone volumes/ports. Edge identifies an immutable source commit and an experimental version; Stable uses an accepted versioned artifact. A moving alias is never rollback evidence. No publication is authorized by drafting this SDD. + +### 6.2 States and alternatives + +PR head -> CI Check queued -> running -> passed/failed/cancelled; only the current relevant head can pass acceptance. Artifact prepared -> tested -> eligible for review -> explicitly published. Experimental validation does not promote production. Restore/rollback selects a compatible image and database backup together. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `coverage_threshold` | percentage | 100 | 100% first-party lines/statements/functions/branches where tools expose them; no blanket exclusions | repository quality invariant | +| `channel` | enum | explicit selection | stable or edge; no automatic promotion | installation; immutable namespace | +| `browser_evidence_retention_days` | integer | 7 | 1..30; sanitized failure artifacts only | CI; persisted by provider | +| `dogfood_target` | URL | http://homeassistant.local:8123/ | owner-authorized local HA target, Google Chrome | manual evidence; not a CI secret | + +These are proposed defaults pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: keep the defaults above. Meaningful alternative: a member selects Spanish and dark theme while the same household policies remain in force. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +A new project-owned CI Check workflow runs domain/application/adapter/UI tests, architecture import/cycle rules, schema and service contracts, English-source conventions, localization, coverage, browser E2E and packaging. It does not edit or call privileged Copilot mutation paths. Test dependencies are provisioned in the job that executes them. Any project dependency setup exception is limited to the existing project-owned preparation action after review. Release tooling consumes tested immutable artifacts with distinct channel manifests. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | CI Check is running for the latest PR commit. No action required. | +| Action required | CI Check needs attention: add the missing permission-denial test before review. | +| Blocked | CI Check failed. No artifact was promoted. Open the failing test report. | +| Partial | Unit and contract tests passed. Local Chrome dogfooding is still pending; this is not release acceptance. | +| Complete | CI Check passed for this commit. Stable and Edge artifacts remain separate and await the authorized release flow. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 24 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Coverage and tests | 4 | the first domain implementation; a module-wide coverage exclusion added to hide missed paths; UI and backend source | +| Architecture contracts | 3 | a domain import of HA or SQL; a frontend view importing a concrete transport adapter; an application port implemented by both deployment adapters | +| Workflow contracts | 6 | a new commit pushed to an open PR; one failed or unexpectedly skipped required job; a newer PR head | +| Deployment and channels | 4 | Stable and Edge installed together; both HA integrations; both standalone channels | +| Integration and recovery | 2 | rollback across an incompatible schema; a test-created task and stock item | +| Security and privacy | 3 | a passed experimental run; existing household data; a failed browser request with an authorization header | +| Browser and accessibility | 2 | local dogfooding; passing unit coverage but absent local Chrome evidence | +| **Total** | **24** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| delivery-quality-C01 | Coverage and tests | delivery-quality-R1 | Given the first domain implementation, a missing branch test fails the 100% branch coverage gate. | +| delivery-quality-C02 | Coverage and tests | delivery-quality-R1 | Given a module-wide coverage exclusion added to hide missed paths, the quality configuration check rejects it. | +| delivery-quality-C03 | Coverage and tests | delivery-quality-R1 | Given UI and backend source, separate reports enforce 100% supported first-party metrics rather than averaging away gaps. | +| delivery-quality-C04 | Architecture contracts | delivery-quality-R2 | Given a domain import of HA or SQL, the architecture job fails. | +| delivery-quality-C05 | Architecture contracts | delivery-quality-R2 | Given a frontend view importing a concrete transport adapter, the dependency rule fails. | +| delivery-quality-C06 | Architecture contracts | delivery-quality-R2 | Given an application port implemented by both deployment adapters, the same behavior contract runs for each. | +| delivery-quality-C07 | Workflow contracts | delivery-quality-R3 | Given a new commit pushed to an open PR, CI Check runs tests even when only documentation paths changed. | +| delivery-quality-C08 | Workflow contracts | delivery-quality-R3 | Given one failed or unexpectedly skipped required job, the aggregate check cannot report success. | +| delivery-quality-C09 | Workflow contracts | delivery-quality-R3 | Given a newer PR head, an older passing run is not accepted as evidence for that head. | +| delivery-quality-C10 | Deployment and channels | delivery-quality-R4 | Given Stable and Edge installed together, their DB volumes and installation credentials differ. | +| delivery-quality-C11 | Deployment and channels | delivery-quality-R4 | Given both HA integrations, entity unique IDs and public selection remain isolated by instance/channel. | +| delivery-quality-C12 | Deployment and channels | delivery-quality-R4 | Given both standalone channels, their configured host bindings do not collide and data is not shared. | +| delivery-quality-C13 | Deployment and channels | delivery-quality-R5 | Given an Edge build, its manifest records its exact source SHA and image digest. | +| delivery-quality-C14 | Integration and recovery | delivery-quality-R5 | Given rollback across an incompatible schema, tooling requires the paired backup and refuses a blind downgrade. | +| delivery-quality-C15 | Security and privacy | delivery-quality-R5 | Given a passed experimental run, no production publish, tag or deploy occurs without explicit release authorization. | +| delivery-quality-C16 | Browser and accessibility | delivery-quality-R6 | Given local dogfooding, evidence records Chrome, artifact digest, channel and exercised workflows. | +| delivery-quality-C17 | Integration and recovery | delivery-quality-R6 | Given a test-created task and stock item, cleanup removes only the recorded test artifacts and reconciles compensations. | +| delivery-quality-C18 | Security and privacy | delivery-quality-R6 | Given existing household data, the dogfooding harness cannot bulk-delete unowned records. | +| delivery-quality-C19 | Coverage and tests | delivery-quality-R7 | Given time and event-replay tests, injected clocks and IDs produce deterministic results without live service waits. | +| delivery-quality-C20 | Security and privacy | delivery-quality-R7 | Given a failed browser request with an authorization header, retained diagnostics redact its credential. | +| delivery-quality-C21 | Browser and accessibility | delivery-quality-R7 | Given passing unit coverage but absent local Chrome evidence, dogfooding remains explicitly unverified. | +| delivery-quality-C22 | Workflow contracts | delivery-quality-R8 | Given the documentation or implementation patch, an immutable baseline comparison detects any changed Copilot-owned file. | +| delivery-quality-C23 | Workflow contracts | delivery-quality-R8 | Given dependency preparation, only the existing project-owned setup action is eligible for the owner's stated exception. | +| delivery-quality-C24 | Workflow contracts | delivery-quality-R8 | Given a future Copilot limitation, the task reports it without patching the bot, weakening checks or inventing evidence. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/delivery-quality.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| delivery-quality-R1 | delivery-quality-C01, delivery-quality-C02, delivery-quality-C03 | +| delivery-quality-R2 | delivery-quality-C04, delivery-quality-C05, delivery-quality-C06 | +| delivery-quality-R3 | delivery-quality-C07, delivery-quality-C08, delivery-quality-C09 | +| delivery-quality-R4 | delivery-quality-C10, delivery-quality-C11, delivery-quality-C12 | +| delivery-quality-R5 | delivery-quality-C13, delivery-quality-C14, delivery-quality-C15 | +| delivery-quality-R6 | delivery-quality-C16, delivery-quality-C17, delivery-quality-C18 | +| delivery-quality-R7 | delivery-quality-C19, delivery-quality-C20, delivery-quality-C21 | +| delivery-quality-R8 | delivery-quality-C22, delivery-quality-C23, delivery-quality-C24 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/home-assistant-surface.md b/specs/home-assistant-surface.md new file mode 100644 index 0000000..a35733d --- /dev/null +++ b/specs/home-assistant-surface.md @@ -0,0 +1,311 @@ +# Home Assistant entities, services and integration + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: home-assistant-surface +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Domus exposes its household capabilities as native Home Assistant entities, services and events. The already integrated HA MCP consumes these surfaces; no gateway work or second MCP is included. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Public service schemas and scope review; technical principal authorization; response-service exposure contract; supported HA matrix. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Domus exposes its household capabilities as native Home Assistant entities, services and events. The already integrated HA MCP consumes these surfaces; no gateway work or second MCP is included. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +Agents and HA automations need stable, bounded ways to query and act on Domus without treating entity state as a complete database or bypassing domain permissions. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: HA user; HA automation; Domus companion integration; existing HA MCP consumer. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| home-assistant-surface-R1 | HA entities MUST have stable unique IDs, bounded attributes and honest unavailable/stale states while Domus remains authoritative. | +| home-assistant-surface-R2 | Public services MUST use validated versioned schemas and bounded structured responses instead of encoding rich data in entity attributes. | +| home-assistant-surface-R3 | Every mutation MUST traverse the same Domus authorization, state, revision, idempotency and audit rules as the UI. | +| home-assistant-surface-R4 | Human and technical principals MUST remain distinct; member_id and caller-provided identity fields cannot grant permissions. | +| home-assistant-surface-R5 | Task and shopping projections MUST preserve occurrence/item identity and refuse unsupported native operations rather than corrupt richer domain states. | +| home-assistant-surface-R6 | HA-facing rule invocations MUST preserve trigger identity, rule revision, technical-principal scope and causal correlation, delegating deduplication/cooldown/loop decisions to the owning Domus automation engine rather than implementing another rule evaluator. | +| home-assistant-surface-R7 | Both deployment targets MUST support reconnection, bounded queries and lifecycle unload without polling storms or leaking credentials. | +| home-assistant-surface-R8 | The integration MUST expose enough query/action metadata for HA consumers while requiring no MCP implementation or gateway modification. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +A companion integration connects to the application through a scoped installation credential and maintains projection cursors and availability. Entities have stable unique IDs based on household/record IDs, independent of renamed entity_ids. Proposed entities: sensor.domus_tasks_due, sensor.domus_tasks_overdue, sensor.domus_low_stock_products, sensor.domus_member_points_, sensor.domus_member_points_balance_, binary_sensor.domus_attention_required, calendar.domus_schedule, optional separate calendar.domus_completion_history, todo.domus_tasks and todo.domus_shopping. Weekly earned points use actual work dates and differ from the possibly negative lifetime balance; pending verification is never spendable credit. Rich fields stay in bounded response services. Service operations and response envelopes are defined in the linked contract document. A technical principal is not a household member and cannot assert a human identity through parameters. + +The complete_task service accepts explicit actual material lines with stable identities and invokes the same combined application orchestration as the UI. Its structured result distinguishes saved completion, verification, points and each posted or pending-regularization material intent. Query/settlement services expose those retained intents within the caller's grants; a stock shortfall must not be reported as failure of already-saved work. A native to-do checkbox cannot supply missing actual performers or confirm planned materials on the caller's behalf. If its supported schema cannot express a required review, reject that native mutation before applying effects and direct the caller to the form or typed service. + +Verified human context resolves the configured administrator mapping and current effective profile/member permissions; technical grants remain distinct even if the transport credential has HA administration. Task queries retain dependency_attention separately from real completed state. Points queries distinguish funding_hold from delivery and include retained approval/reservation status within permitted scope. Disabling a stored rule through HA has the same durable stopping boundary as the UI: new runs/later steps stop while already-started atomic commands settle visibly. None of these adapters applies an alternate authorization, dependency or affordability policy. + +### 6.2 States and alternatives + +Integration setup -> connected -> stale/unavailable -> reconnecting -> connected. A command returns completed, pending projection, conflict, denied, invalid or unavailable with an operation ID. A transport timeout means outcome unknown until receipt lookup; no automatic fresh-key retry. External HA automations may call typed Domus commands or invoke a stored Domus rule with stable trigger identity and causal correlation. The in-application simple/advanced editors and durable execution policy belong to [household automation](household-automation.md); this integration owns only their HA entrypoint mapping. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `integration_enabled` | boolean | true | explicitly configured per installation | installation; persisted | +| `projection_poll_seconds` | integer | 30 | 5..300 as fallback; push notifications preferred | integration; restart-safe cursor | +| `service_max_items` | integer | 100 | 1..200; pagination required | request; not persisted | +| `automation_mutations_enabled` | boolean | false | explicit scoped grants required | installation; revocation checked per command | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: native projections and typed queries with automation mutations disabled. Meaningful alternative: explicitly grant a technical principal one bounded action while all domain authorization and receipt rules remain enforced. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +The companion integration adapts public HA entity/service APIs to Domus QueryHousehold and CommandHousehold use cases. Credentials stay server-side and are distinct from human authentication. A verified HA user context can map to that user's Domus role; absent or automation context uses only explicitly configured technical grants. member_id selects an authorized target, never authenticates the caller. No arbitrary proxy to Domus HTTP or Python execution is exposed. Native task/shopping entities are projections of Domus records, not independent stores or mirrors of unrelated HA lists. + +Automation rule list/preview/run/enable adapters call the owning engine ports. They cannot compile a different DSL, apply their own collaboration points algorithm or maintain independent cooldown policy. Direct task/shopping commands continue to use their domain command receipts; invoking a stored rule additionally uses that rule's admitted trigger and durable run state. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Connecting Domus entities to Home Assistant. | +| Action required | This automation needs permission to create maintenance tasks. Review its Domus service grants. | +| Blocked | Home Assistant rejected this command. No household data changed. Review the service error code. | +| Partial | The task is complete in Domus. Home Assistant is refreshing its projection. View operation. | +| Complete | Domus entities and services are connected. View the Home Assistant contract. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 33 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Adapters and HA contracts | 12 | a renamed task entity; a query with more items than its page limit; a response-service call | +| UI and accessibility | 1 | a disconnected backend | +| Deployment and contracts | 3 | a large household; standalone Core API access; service discovery | +| Domain and configuration | 2 | unknown service fields or unsupported contract version; an event caused by the same automation correlation | +| State and concurrency | 3 | a repeated HA completion command; a stale expected revision; replay of the same sensor-trigger identity | +| Security and privacy | 6 | a service principal without stock-correction grant; a caller-supplied administrator member_id; an HA automation without verified human context | +| Integration and recovery | 6 | backend item changes; an automation disabled during a pending retry; disconnect and reconnect | +| **Total** | **33** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| home-assistant-surface-C01 | Adapters and HA contracts | home-assistant-surface-R1 | Given a renamed task entity, its registry unique ID and underlying task identity stay stable. | +| home-assistant-surface-C02 | UI and accessibility | home-assistant-surface-R1 | Given a disconnected backend, entity availability changes to unavailable rather than falsely reporting zero tasks. | +| home-assistant-surface-C03 | Deployment and contracts | home-assistant-surface-R1 | Given a large household, sensor attributes contain counts and bounded metadata rather than all records. | +| home-assistant-surface-C04 | Adapters and HA contracts | home-assistant-surface-R2 | Given a query with more items than its page limit, a cursor is returned without silent truncation. | +| home-assistant-surface-C05 | Domain and configuration | home-assistant-surface-R2 | Given unknown service fields or unsupported contract version, validation rejects the request. | +| home-assistant-surface-C06 | Adapters and HA contracts | home-assistant-surface-R2 | Given a response-service call, its result distinguishes empty success from upstream unavailability. | +| home-assistant-surface-C07 | State and concurrency | home-assistant-surface-R3 | Given a repeated HA completion command, one completion and one award allocation exist. | +| home-assistant-surface-C08 | State and concurrency | home-assistant-surface-R3 | Given a stale expected revision, the service returns conflict and applies no change. | +| home-assistant-surface-C09 | Security and privacy | home-assistant-surface-R3 | Given a service principal without stock-correction grant, the domain rejects its correction command. | +| home-assistant-surface-C10 | Security and privacy | home-assistant-surface-R4 | Given a caller-supplied administrator member_id, the service does not elevate the authenticated principal. | +| home-assistant-surface-C11 | Security and privacy | home-assistant-surface-R4 | Given an HA automation without verified human context, only its technical grant scope is used. | +| home-assistant-surface-C12 | Adapters and HA contracts | home-assistant-surface-R4 | Given a verified HA user context, permissions resolve to the linked active member and revocation still applies. | +| home-assistant-surface-C13 | Adapters and HA contracts | home-assistant-surface-R5 | Given native to-do completion of a task requiring verification, the projection preserves awaiting-verification semantics. | +| home-assistant-surface-C14 | Adapters and HA contracts | home-assistant-surface-R5 | Given native removal of a ledger-backed shopping item, the adapter rejects unsupported deletion and explains cancellation. | +| home-assistant-surface-C15 | Integration and recovery | home-assistant-surface-R5 | Given backend item changes, to-do projections retain stable UIDs across refresh and restart. | +| home-assistant-surface-C16 | State and concurrency | home-assistant-surface-R6 | Given replay of the same sensor-trigger identity, exactly one maintenance occurrence is created. | +| home-assistant-surface-C17 | Domain and configuration | home-assistant-surface-R6 | Given an event caused by the same automation correlation, loop detection suppresses retriggering. | +| home-assistant-surface-C18 | Integration and recovery | home-assistant-surface-R6 | Given an automation disabled during a pending retry, no new mutation executes after revocation. | +| home-assistant-surface-C19 | Deployment and contracts | home-assistant-surface-R7 | Given standalone Core API access, integration queries and services run without Supervisor assumptions. | +| home-assistant-surface-C20 | Integration and recovery | home-assistant-surface-R7 | Given disconnect and reconnect, projections resume from a cursor and reconcile missing events once. | +| home-assistant-surface-C21 | Adapters and HA contracts | home-assistant-surface-R7 | Given integration unload, listeners and polling are cancelled without deleting business data. | +| home-assistant-surface-C22 | Deployment and contracts | home-assistant-surface-R8 | Given service discovery, HA exposes registered schemas, selectors and response support for each proposed action. | +| home-assistant-surface-C23 | Security and privacy | home-assistant-surface-R8 | Given diagnostic export, no installation token, upstream token or unbounded user payload is included. | +| home-assistant-surface-C24 | Integration and recovery | home-assistant-surface-R8 | Given no gateway process during Domus acceptance, normal UI workflows and HA entity/service tests still pass. | +| home-assistant-surface-C25 | Adapters and HA contracts | home-assistant-surface-R2, home-assistant-surface-R3 | Given complete_task with explicit material lines and a stock shortfall, the response identifies the saved completion and pending intent separately; identical-key replay duplicates neither. | +| home-assistant-surface-C26 | Security and privacy | home-assistant-surface-R3, home-assistant-surface-R4 | Given a technical principal allowed to complete tasks but lacking a requested stock-movement grant, the combined submission cannot use task permission to bypass inventory authorization. | +| home-assistant-surface-C27 | Adapters and HA contracts | home-assistant-surface-R5 | Given a native to-do checkbox that cannot express required performer/material review, the adapter rejects the mutation before effects and offers the supported UI/service path without silently consuming estimates. | +| home-assistant-surface-C28 | Integration and recovery | home-assistant-surface-R2, home-assistant-surface-R8 | Given an authorized material-intent query and repeated settlement request, the same source intent and validated movement remain discoverable once with bounded results and no gateway change. | +| home-assistant-surface-C29 | Adapters and HA contracts | home-assistant-surface-R1, home-assistant-surface-R2 | Given delayed approval or a spent-point reversal, HA projections preserve work-week totals separately from current possibly-negative balance and query results distinguish pending from spendable points. | +| home-assistant-surface-C30 | Security and privacy | home-assistant-surface-R3, home-assistant-surface-R4 | Given configured administrator mapping and member exceptions, verified human service context uses current effective permissions while a technical credential or supplied administrator flag cannot inherit the human mapping. | +| home-assistant-surface-C31 | Integration and recovery | home-assistant-surface-R2, home-assistant-surface-R6 | Given HA disabling a rule during an atomic action, the response/query distinguishes disabled admission from its settling action; no later step or old wait resumes after restart/re-enable. | +| home-assistant-surface-C32 | Adapters and HA contracts | home-assistant-surface-R2, home-assistant-surface-R3 | Given reopening a prerequisite via HA, completed dependent queries retain completion/points with a linked review condition and no cascading mutation. | +| home-assistant-surface-C33 | Adapters and HA contracts | home-assistant-surface-R2, home-assistant-surface-R3 | Given an authorized query after backing points are reversed, an approved unfulfilled redemption is shown as held with its reservation and missing funding, never as delivered or silently cancelled. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/home-assistant-surface.md | create | +| specs/household-automation.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| home-assistant-surface-R1 | home-assistant-surface-C01, home-assistant-surface-C02, home-assistant-surface-C03, home-assistant-surface-C29 | +| home-assistant-surface-R2 | home-assistant-surface-C04, home-assistant-surface-C05, home-assistant-surface-C06, home-assistant-surface-C25, home-assistant-surface-C28, home-assistant-surface-C29, home-assistant-surface-C31, home-assistant-surface-C32, home-assistant-surface-C33 | +| home-assistant-surface-R3 | home-assistant-surface-C07, home-assistant-surface-C08, home-assistant-surface-C09, home-assistant-surface-C25, home-assistant-surface-C26, home-assistant-surface-C30, home-assistant-surface-C32, home-assistant-surface-C33 | +| home-assistant-surface-R4 | home-assistant-surface-C10, home-assistant-surface-C11, home-assistant-surface-C12, home-assistant-surface-C26, home-assistant-surface-C30 | +| home-assistant-surface-R5 | home-assistant-surface-C13, home-assistant-surface-C14, home-assistant-surface-C15, home-assistant-surface-C27 | +| home-assistant-surface-R6 | home-assistant-surface-C16, home-assistant-surface-C17, home-assistant-surface-C18, home-assistant-surface-C31 | +| home-assistant-surface-R7 | home-assistant-surface-C19, home-assistant-surface-C20, home-assistant-surface-C21 | +| home-assistant-surface-R8 | home-assistant-surface-C22, home-assistant-surface-C23, home-assistant-surface-C24, home-assistant-surface-C28 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/household-automation.md b/specs/household-automation.md new file mode 100644 index 0000000..667ab15 --- /dev/null +++ b/specs/household-automation.md @@ -0,0 +1,300 @@ +# Household automation engine and simple/advanced rule editors + +- Status: Draft +- Date: 2026-10-29 +- Catalog capability ID: household-automation +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Simple/default and optional advanced editors share one durable declarative automation engine in the first release, invoking authorized household commands with replay-safe execution and visible traces. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2; https://github.com/vypdev/domus/pull/3 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed DSL/action catalog, numeric resource limits, external-effect receipts and supported HA/browser evidence. The owner confirmed both editors, one engine and disablement that stops new runs/later steps while retaining already-started atomic commands and effects. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +The owner confirmed both simple/default and optional advanced automation editing in the first release on 2026-10-29. One declarative engine executes both; Domus remains useful without AI or an available MCP gateway. + +```text +Rule editor -> validate and preview -> explicit enable -> durable trigger/run -> authorized domain steps -> visible results +``` + +## 2. Problem, current behavior, and evidence + +Domus has no implemented rule engine yet. HA-facing commands alone do not provide the in-application simple and advanced experiences now requested by the owner. The existing gateway is already integrated and is not changed. HA's automation model, concurrency modes and traces are design references, not a backend to reconfigure or a compatibility promise. + +Evidence: owner decisions in [decisions](../docs/decisions.md), the [product vision](../docs/product-vision.md) and primary references in section 20. This is prospective; retrospective classification is not applicable. + +## 3. Actors, surfaces, and terminology + +An administrator authors/enables rules and grants technical execution scope. Members view permitted results and may invoke authorized manual triggers. A rule principal is distinct from the member named in an action. + +RuleDefinition is mutable through revision-controlled edits; RuleRevision is immutable declarative data. TriggerEvent, ConditionTree, ActionPlan, AutomationRun, StepReceipt, WaitDeadline and ExecutionTrace have stable identities. The native HA surface adapts entrypoints; this capability owns internal rule semantics. + +## 4. Goals, non-goals, and fixed invariants + +| Requirement | Behavior | +|---|---| +| household-automation-R1 | Both first-release editors MUST use one versioned declarative rule model, with simple as the default and optional advanced editing that cannot silently discard unsupported fields. | +| household-automation-R2 | Triggers, condition trees and action plans MUST use validated typed schemas with explicit resource bounds; arbitrary code, unbounded loops and raw network/database access are excluded. | +| household-automation-R3 | Every action MUST call the same authorized Domus application use case as the UI, rechecking principal grants and target scope before each side effect. | +| household-automation-R4 | Execution MUST durably persist run identity, pinned rule revision, waits and step receipts and remain duplicate-safe across concurrent workers, retries and restart. | +| household-automation-R5 | Editing MUST preserve active run snapshots; disabling MUST prevent new runs and later steps, finish/record already-started atomic commands and retain their effects; cancellation and partial failure MUST expose actual retained outcomes rather than claim rollback. | +| household-automation-R6 | Causal correlation, cooldown, bounded concurrency/repetition and loop detection MUST prevent duplicate or cyclic automation storms while preserving inspectable suppression reasons. | +| household-automation-R7 | Preview and simulation MUST explain triggers, conditions and proposed effects without side effects; real execution retains sanitized per-step history, policy revisions and actual outcomes. | +| household-automation-R8 | Automation UI and HA-facing operations MUST expose understandable pending, action-required, denied/failed, partial and completed states with accessible English/Spanish presentation and permission-aware bounded queries. | +| household-automation-R9 | The same engine MUST satisfy Clean Architecture and meaningful tests from first implementation, with both deployment targets and isolated Stable/Edge channels; Copilot and the existing gateway remain unchanged. | + +Non-goals: arbitrary scripts, SQL/network passthrough, unbounded loops, rewriting HA automation files, replacing domain recurrence/replenishment invariants, or creating another MCP server. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | Effect | +|---|---|---|---| +| Configure | No Domus rule UI | Simple form or optional advanced flow editor | Same versioned rule data | +| Preview | No simulation | Explain trigger/conditions and intended steps | No side effects | +| Enable | No runtime | Explicit validated revision and scoped principal | Safe admission | +| Execute | No durable run | Persist trigger, plan, waits and step receipts | Restart/replay correctness | +| Recover | No trace | Explain committed effects and safe retry/cancel | Honest partial success | + +```mermaid +flowchart LR + Simple[Simple editor] --> Rule[One rule revision] + Advanced[Advanced editor] --> Rule + Rule --> Plan[Pure validation and plan] + Plan --> Run[Durable run] + Run --> Commands[Authorized domain commands] + Run --> Trace[Visible trace] +``` + +Text equivalent: both editors save one rule model; pure compilation feeds durable execution, which calls domain commands and records a trace. + +## 6. Functional behavior and state model + +### 6.1 Rule and execution model + +Simple mode covers one typed trigger, optional conditions and a short sequence of catalogued actions. Advanced mode adds nested AND/OR/NOT, choose/branch, bounded repeat/for-each, multiple steps, durable delays/waits and bounded parallelism. Typed triggers cover domain events, selected HA state/event changes, schedules and explicit manual invocation. A state crossing is distinct from testing an already-true condition. Rule policy never recalculates points, inventory consolidation or recurrence: it invokes the owning domain use case. + +Actions initially create/assign tasks, create attributable shopping demand, request explicit stock commands within grants and send configured notifications. Supported HA operations enter through reviewed typed adapters rather than arbitrary proxies. Every action records its operation ID and real result. Rules and run IDs include household/instance/channel scope. + +### 6.2 State and lifecycle + +Rule: draft -> validated -> enabled <-> disabled -> archived. Run: queued -> running -> waiting -> running -> completed; denied, failed, partial, timed_out and cancelled are explicit terminal outcomes. Cancellation requested during an atomic command finishes/records that command and prevents subsequent steps. + +A run pins its rule revision, action plan and policy at admission. Editing affects new triggers. The owner confirmed that disablement suppresses new runs and prevents subsequent steps in queued, waiting or active runs. An atomic domain command already started may finish; its real receipt and effects remain visible. Disable admission and step admission serialize through a durable rule control revision: a worker's old enablement check is not enough to start another action after disablement. In parallel branches, only commands already started may settle; no new branch action starts. Persist the stop reason and cancellation request across restart. Re-enabling the rule admits future triggers but does not silently resume the old cancelled queue or waits. The disable response distinguishes authoritative disabled state from in-flight commands whose outcomes are still settling. + +A safe retry resumes only failed/pending steps using their original command keys and current grants; it cannot clear a disablement cancellation or bypass the rule's current enablement. Explicitly reviewed future execution is separate from automatically resuming cancelled work. Permissions and enablement are rechecked before each new action. Unsupported compensation is reported as retained effect; disablement does not automatically undo successful domain or external actions. + +The proposed default is serial execution per rule, with explicit skip_while_running and bounded_parallel alternatives. Wait deadlines, leases and cursors persist. Trigger identity plus rule revision deduplicates admissions; per-step keys deduplicate commands. Causal rule IDs/hop budgets detect loops across rules and external HA events. Cooldown limits frequency but does not establish idempotency. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| editor_mode | enum | simple | simple or advanced; changing views preserves the rule model | member preference; rule stores representability metadata | +| rule_enabled | boolean | false | explicit enable after validation/preview | rule; current value rechecked before each effect | +| execution_mode | enum | serial | serial, skip_while_running, bounded_parallel | rule revision snapshot | +| parallel_run_limit | integer | 2 | 1..4, only for bounded_parallel | rule revision; global resource cap also applies | +| cooldown_seconds | integer | 300 | 0..86400; zero allowed only with intact deduplication and causal bounds | rule revision snapshot | +| rule_node_limit | integer | 64 | fixed proposed maximum; condition depth <=8 and at most 32 effect nodes | validation invariant, not an escape hatch | +| repetition_limit | integer | 50 | 1..50 and total executable-step budget <=256 | validated plan and run receipt | +| wait_seconds | integer | explicit per wait | 0..2592000; no wait resets after restart | durable absolute deadline | +| queued_run_limit | integer | 100 | per-rule maximum, global queued maximum 1000 | durable admission accounting | + +These numeric limits are explicit engineering proposals pending resource tests; no readiness claim depends on them being final. Invalid combinations fail before saving. Example default: a disabled simple rule, one low-stock trigger, one demand action, serial mode. Alternative: an enabled advanced branch with a bounded wait and two parallel runs. Invariants outrank installation limits, which outrank household/rule choices. Revocation/disablement is current; run semantics and policy versions are snapshotted. Unknown schema versions fail closed without rewriting saved rules. + +## 8. Clean Architecture design + +### 8.1 Boundaries + +Domain owns typed conditions, pure plan validation, bounded decision policies and state transitions. Application owns ValidateRule, SimulateRule, AdmitTrigger, AdvanceAutomationRun, CancelRun and RetryRun. Semantic ports include RuleRepository, RunRepository, DurableScheduler, DomainCommandPort, AuthorizationPort, Clock, EventInbox and TraceSink. SQLite, HA transport and notification providers are adapters; composition wires the selected deployment. + +UI editors map one schema to view models; they do not execute policy. The native HA adapter delegates to this engine instead of implementing a second rule evaluator. DomainCommandPort routes to existing task, points, stock and shopping use cases; it cannot bypass their ledgers or permissions. + +### 8.2 Durable state and architecture checks + +Admission and trigger receipt commit atomically. Each step uses a stable run/node/iteration command key. Its durable receipt resolves a crash or lost response without duplicating the owning domain effect. External notification effects without idempotent receipt support report ambiguous outcome and require explicit review before re-sending. + +Executable import/cycle rules reject infrastructure in domain/application and API calls inside presentation primitives. Schema fixtures validate both editors; port contracts verify step/receipt semantics. No broker, second MCP or Copilot change is introduced. + +## 9. UI/UX and content contract + +| State | Primary content | +|---|---| +| Pending | Filter reminder is waiting until 18:00. The earlier task was saved. No action required. | +| Action required | This rule has advanced branching. Open the advanced editor to change it; your rule is retained. | +| Blocked | Create-task permission was revoked. No new step ran. Review the rule's grants. | +| Partial | The maintenance task was created, but its notification failed. View the task or retry the notification. | +| Complete | Filter reminder completed. One task was created and its notification was sent. View execution history. | + +Settings -> Automations provides rule list, simple/advanced editor, validation/preview, enable/disable, run history and per-step trace. The outer HA shell is not duplicated. Simple mode renders unsupported advanced content as a summary, not an editable lossy projection. English/Spanish, keyboard flow editing, visible focus, non-color branch/status labels, narrow layouts and reduced motion are acceptance gates. At most one routine notification per meaningful transition; retried steps update the same run view. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained result | Action | +|---|---|---| +| Invalid plan or denied admission | Saved prior rule; no run effect | Correct highlighted fields or grants | +| False condition | Inspectable no-action decision | No retry required | +| Crash during durable wait | Original absolute deadline and cursor | Resume once after restart | +| Lost command response | Stable domain operation key | Lookup/replay original receipt | +| Later step fails | Successful prior step receipts and real domain records | Retry only supported failed work | +| Disable/cancel after effects | Existing successful effects and cancellation trace | Stop later steps; compensate only through explicit supported commands | +| Queue/loop budget reached | Suppression reason and causal IDs | Inspect rule and limit; never silently drop a committed domain result | + +Cleanup releases owned listeners/leases and temporary simulation state; it never deletes business ledgers or another channel's records. Retries use bounded backoff and per-step receipts. + +## 11. Security, permissions, and privacy + +Only an authorized principal may author/enable or manually invoke effects. Technical rule grants are narrow and do not inherit a role from member_id. Recheck rights per action. Conditions and schemas accept data, never executable code. Cross-instance IDs, hostile expressions, event floods and forged HA context fail before side effects. Tokens/private payloads are absent from rules, exported traces and browser artifacts; export includes only permitted sanitized identifiers and decisions. + +## 12. Observability and operational UX + +Members see current run state, saved facts and a single next action. Operators see bounded rule revision, trigger/run/step IDs, correlation chain, duration, decision code, attempt and receipt references. Metrics distinguish condition false, suppressed, denied, unavailable, partial and completed. A failed notification is not a failed task creation. Trace retention is bounded independently of immutable business ledgers; proposed 30 days for routine traces and explicit export before pruning. + +## 13. Compatibility, migration, rollout, and rollback + +No Domus automation data exists yet. Schemas are versioned from first implementation. Editors preserve unknown future revisions by refusing unsupported edits. Migrations cover enabled rules, queued/waiting runs and receipts; compatible image/database backups are required for downgrade. Both Supervisor and standalone include simple and advanced modes at first release; Stable/Edge never share rules, cursors or service credentials. Publication remains separately authorized. + +## 14. Testing strategy and numeric budget + +Minimum: 45 distinct cases, derived from the editor, DSL, permission, durable-run, recovery and loop risk inventory. Cases are planned, not executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Editors and schema | 4 | Explicit editors and schema scenarios below | +| UI and accessibility | 4 | Explicit ui and accessibility scenarios below | +| Domain and planning | 7 | Explicit domain and planning scenarios below | +| Security and permissions | 5 | Explicit security and permissions scenarios below | +| Adapters and contracts | 4 | Explicit adapters and contracts scenarios below | +| State and durability | 11 | Explicit state and durability scenarios below | +| Integration and recovery | 6 | Explicit integration and recovery scenarios below | +| Deployment and architecture | 4 | Explicit deployment and architecture scenarios below | +| **Total** | **45** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| household-automation-C01 | Editors and schema | household-automation-R1 | Given a simple rule, opening it in the advanced editor preserves the exact rule revision and execution semantics. | +| household-automation-C02 | Editors and schema | household-automation-R1 | Given an advanced branch/wait not representable in the simple form, simple mode shows a non-destructive summary and directs editing to advanced mode. | +| household-automation-C03 | Editors and schema | household-automation-R1 | Given a simple-editor save, unknown advanced fields are never silently removed or defaulted. | +| household-automation-C04 | UI and accessibility | household-automation-R1 | Given a new household, rule creation starts in the simple editor and advanced mode remains an explicit optional choice. | +| household-automation-C05 | Domain and planning | household-automation-R2 | Given a typed household event and matching condition tree, compilation produces a deterministic bounded plan. | +| household-automation-C06 | Domain and planning | household-automation-R2 | Given nested AND/OR/NOT conditions, pure evaluation returns the expected decision and a structured explanation. | +| household-automation-C07 | Editors and schema | household-automation-R2 | Given an unknown schema version or action type, validation rejects the rule without replacing its saved revision. | +| household-automation-C08 | Security and permissions | household-automation-R2 | Given embedded script, SQL, arbitrary URL or unsafe expression text, compilation refuses execution. | +| household-automation-C09 | Domain and planning | household-automation-R2 | Given excess condition depth, node count, wait duration or repetition count, validation names the exceeded bound without truncating the plan. | +| household-automation-C10 | Domain and planning | household-automation-R2 | Given a numeric-state crossing trigger, an already-true initial state does not masquerade as a new crossing; explicit state-condition/manual behavior is distinct. | +| household-automation-C11 | Security and permissions | household-automation-R3 | Given a technical rule principal without task-assignment grant, its assignment step is denied before mutation. | +| household-automation-C12 | Security and permissions | household-automation-R3 | Given a caller-provided administrator member ID, run authorization does not elevate the trusted rule principal. | +| household-automation-C13 | Security and permissions | household-automation-R3 | Given grant revocation while a run is waiting, the next action is denied without undoing prior authorized facts. | +| household-automation-C14 | Adapters and contracts | household-automation-R3 | Given equivalent rule and direct UI task commands, both use the same transition/verification/points policies. | +| household-automation-C15 | State and durability | household-automation-R4 | Given duplicate delivery of the same trigger event to the same rule revision, one run and one set of action receipts exist. | +| household-automation-C16 | State and durability | household-automation-R4 | Given a crash after a task step commits but before the engine records its local status, recovery replays the same command key and retains one task. | +| household-automation-C17 | State and durability | household-automation-R4 | Given a durable wait and process restart, the saved deadline resumes without restarting the delay from zero. | +| household-automation-C18 | State and durability | household-automation-R4 | Given two executors claiming one run, lease/revision fencing permits only one effective step transition. | +| household-automation-C19 | State and durability | household-automation-R4 | Given two distinct admitted trigger events, receipts remain distinct while the selected concurrency mode is enforced. | +| household-automation-C20 | Integration and recovery | household-automation-R4 | Given a lost step response, receipt lookup/replay resolves the known operation instead of creating a fresh-key duplicate. | +| household-automation-C21 | State and durability | household-automation-R5 | Given a rule edit during execution, the active run keeps its pinned revision and a later trigger uses the new revision. | +| household-automation-C22 | State and durability | household-automation-R5 | Given rule disablement, new triggers are suppressed and queued/waiting runs stop before their next action under the owner-confirmed policy. | +| household-automation-C23 | State and durability | household-automation-R5 | Given cancellation during one atomic domain action, that action's real result is retained and no subsequent step starts. | +| household-automation-C24 | Integration and recovery | household-automation-R5 | Given the second action failing after the first succeeded, status is partial and lists both the committed result and failed step. | +| household-automation-C25 | Integration and recovery | household-automation-R5 | Given retry of a partial run, completed steps keep their receipts and only the safe failed/pending portion resumes. | +| household-automation-C26 | Integration and recovery | household-automation-R5 | Given an external effect that has no supported compensation, cancellation reports it as retained rather than claiming rollback. | +| household-automation-C27 | Domain and planning | household-automation-R6 | Given a causal event returning to a rule already in the same chain, loop policy suppresses the re-entry and records its reason. | +| household-automation-C28 | Domain and planning | household-automation-R6 | Given an otherwise valid repeat trigger within its cooldown, execution is suppressed without treating cooldown as event deduplication. | +| household-automation-C29 | State and durability | household-automation-R6 | Given bounded repeat or parallel execution, the fixed step/run budgets stop further work at the limit with an inspectable result. | +| household-automation-C30 | Integration and recovery | household-automation-R6 | Given an event flood, admission respects per-rule/global queue bounds and reports rejected work rather than allocating unbounded memory. | +| household-automation-C31 | Domain and planning | household-automation-R7 | Given simulation, trigger/condition/step decisions are produced without task, points, stock, notification or HA side effects. | +| household-automation-C32 | UI and accessibility | household-automation-R7 | Given a false condition, the explanation identifies the tested predicate and why no action ran without exposing another member's private data. | +| household-automation-C33 | Adapters and contracts | household-automation-R7 | Given a real execution, audit links rule revision, trigger, operation and each actual result through one correlation chain. | +| household-automation-C34 | Security and permissions | household-automation-R7 | Given a provider error containing a token or private payload, logs and downloadable traces expose only redacted safe diagnostics. | +| household-automation-C35 | UI and accessibility | household-automation-R8 | Given pending, denied, failed, partial and completed runs, each view states what happened, what is retained and one next action. | +| household-automation-C36 | UI and accessibility | household-automation-R8 | Given narrow-screen keyboard use, rule branching controls have accessible names, focus order and English/Spanish messages. | +| household-automation-C37 | Adapters and contracts | household-automation-R8 | Given HA queries or explicit run/enable actions, schemas validate instance/rule IDs, permissions, revisions, idempotency and bounded responses. | +| household-automation-C38 | Adapters and contracts | household-automation-R8 | Given Domus or HA unavailability, projection and run views distinguish stale/unavailable data from successful empty results. | +| household-automation-C39 | Deployment and architecture | household-automation-R9 | Given an automation domain module importing HA, HTTP or SQL, the executable dependency check rejects the boundary violation. | +| household-automation-C40 | Deployment and architecture | household-automation-R9 | Given the same deterministic automation fixture in Supervisor and standalone modes, commands and run outcomes agree. | +| household-automation-C41 | Deployment and architecture | household-automation-R9 | Given Stable and Edge with equivalent rules, an event or credential from one instance cannot execute the other's rule. | +| household-automation-C42 | Deployment and architecture | household-automation-R9 | Given the first engine implementation, CI Check enforces meaningful first-party coverage and contract checks without editing Copilot or gateway files. | +| household-automation-C43 | State and durability | household-automation-R4, household-automation-R5 | Given disablement racing a worker's step admission, the durable control revision prevents any action admitted after disablement while an already-started atomic command retains its actual result. | +| household-automation-C44 | Integration and recovery | household-automation-R4, household-automation-R5 | Given a disabled rule with saved waits and queued work, restart then re-enable does not resume those cancelled runs or reset their waits; only new admitted triggers may execute. | +| household-automation-C45 | State and durability | household-automation-R5 | Given parallel branches when disablement commits, already-started commands may settle with linked receipts but no branch starts another action or automatically compensates a retained effect. | + +Each row counts once. The first implementation includes deterministic clocks, IDs, injected crash points, lease races and adapter fakes, with 100% supported first-party coverage metrics in CI Check. Semantic UI assertions supplement reviewed golden fixtures; no real waits or live HA is required for unit/contract tests. Disposable HA proves integration contracts; controlled Google Chrome dogfooding on the owner's authorized local HA proves actual UI use and records cleanup. Local browser evidence does not replace automated coverage. + +## 15. Documentation and discoverability + +| Path | Change | +|---|---| +| specs/household-automation.md | create | +| specs/home-assistant-surface.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| docs/adr/0005-one-automation-engine.md | create | +| README.md | update | + +[User guide](../docs/user-guide.md) covers creating, previewing and understanding a rule. [Operations](../docs/operations.md) covers grants, waits, partial success, restart, cancellation and cleanup. [Architecture](../docs/architecture.md) and [HA contract](../docs/contracts/home-assistant.md) explain ownership and typed entrypoints. [Acceptance plan](../docs/acceptance-plan.md) tracks original validators, actual implementation tests, both targets/channels and browser evidence. Documentation and contract fixtures change with behavior. + +## 16. Acceptance scenarios + +The section-14 Given/action/result rows are the executable acceptance inventory. The critical complete journey is: create a simple maintenance rule, preview it without effects, enable it, admit a HA/domain event, create exactly one task, survive restart during a wait, show a later notification failure as partial, and retry only that notification. Advanced-editor round trips, revocation during waits, rule edits, flood/cycle suppression and channel isolation are equally required. Human acceptance reviews narrow-screen editing, keyboard and trace readability. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| household-automation-R1 | household-automation-C01, household-automation-C02, household-automation-C03, household-automation-C04 | +| household-automation-R2 | household-automation-C05, household-automation-C06, household-automation-C07, household-automation-C08, household-automation-C09, household-automation-C10 | +| household-automation-R3 | household-automation-C11, household-automation-C12, household-automation-C13, household-automation-C14 | +| household-automation-R4 | household-automation-C15, household-automation-C16, household-automation-C17, household-automation-C18, household-automation-C19, household-automation-C20, household-automation-C43, household-automation-C44 | +| household-automation-R5 | household-automation-C21, household-automation-C22, household-automation-C23, household-automation-C24, household-automation-C25, household-automation-C26, household-automation-C43, household-automation-C44, household-automation-C45 | +| household-automation-R6 | household-automation-C27, household-automation-C28, household-automation-C29, household-automation-C30 | +| household-automation-R7 | household-automation-C31, household-automation-C32, household-automation-C33, household-automation-C34 | +| household-automation-R8 | household-automation-C35, household-automation-C36, household-automation-C37, household-automation-C38 | +| household-automation-R9 | household-automation-C39, household-automation-C40, household-automation-C41, household-automation-C42 | + +Pure policies own plan/condition/budget decisions; application use cases own durable execution and authorization; adapters own schema/provider mapping; presentation owns editor and trace states. Requirements link exactly to the case inventory in both directions. User/operator evidence is linked in section 15. + +## 18. Implementation sequence + +1. Review the typed schema, action catalog, resource bounds and lifecycle contracts. +2. Establish CI Check, meaningful tests and executable dependency rules before implementing engine code. +3. Implement pure conditions, compilation and preview; verify zero simulation effects. +4. Implement durable admission, receipts, waits, leases and partial/retry/cancel behavior with failure injection. +5. Add thin native HA/notification adapters and both deployment profiles. +6. Build simple and advanced editors over the same contracts, with Storybook/Playwright and localization/accessibility. +7. Verify both channels, schema migration, security, docs and controlled Chrome dogfooding before release acceptance. + +Both editors are launch scope; internal sequencing is not a proposal to defer advanced mode. + +## 19. Definition of Done + +- [ ] All nine requirements have reciprocal case links and observable assertions. +- [ ] The planned 42-case floor and complete behavior/coverage gates pass with real implementation. +- [ ] Both editors preserve one schema and all unsupported advanced fields. +- [ ] Permission, deduplication, waits, races, limits, partial recovery and safe cancellation are tested. +- [ ] Clean Architecture checks and 100% supported first-party coverage pass in CI Check. +- [ ] User/setup/operator docs and typed HA schemas agree with actual code. +- [ ] Desktop/mobile, keyboard, English/Spanish, themes and trace readability have evidence. +- [ ] Both deployment targets and Stable/Edge isolation pass. +- [ ] Catalog implementation evidence is real; no Copilot/gateway modification or weakened validation occurred. +- [ ] Material schema/resource/recovery decisions are resolved before Ready for implementation; no implementation/readiness claim is inferred from this Draft. + +## 20. References and decisions + +Owner decisions are recorded in [decisions](../docs/decisions.md). Related contracts: [HA surface](home-assistant-surface.md) and [architecture](../docs/architecture.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. + +[ADR 0005](../docs/adr/0005-one-automation-engine.md) records the accepted product direction while preserving the detailed engine's Draft review gates. + +Primary design references: [HA automation concepts](https://www.home-assistant.io/docs/automation/), [execution modes](https://www.home-assistant.io/docs/automation/modes/), [building blocks](https://www.home-assistant.io/docs/automation/building-blocks/) and [troubleshooting/traces](https://www.home-assistant.io/docs/automation/troubleshooting/). These inform explicit Domus choices, not an assertion that its semantics are identical to HA or that HA/gateway code will be changed. The original [Copilot template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md) supplies the twenty-section format. diff --git a/specs/household-identity.md b/specs/household-identity.md new file mode 100644 index 0000000..6051099 --- /dev/null +++ b/specs/household-identity.md @@ -0,0 +1,314 @@ +# Household members, Home Assistant identity and permissions + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: household-identity +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Each participating person uses their own Home Assistant account. Domus associates that verified user with one household member and applies explicit backend permissions independently of an optional person entity. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed permission matrix/override review; authenticated recovery after external HA account loss; proof of HA identity/administrator status in both deployment targets; technical service principal policy. The owner confirmed three administrator-mapping modes with all HA administrators as the default, plus configurable household profiles and per-member permission exceptions. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Each participating person uses their own Home Assistant account. Domus associates that verified user with one household member and applies explicit backend permissions independently of an optional person entity. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +HA users and person entities have different meanings. The owner confirmed individual HA accounts for every participant; a shared adult identity or independent Domus PIN would contradict that requirement. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Administrator; adult member; restricted member; read-only member; scoped automation principal. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| household-identity-R1 | Every participating member MUST map to a distinct verified HA user; person entities MUST NOT authenticate users. | +| household-identity-R2 | Permissions MUST be enforced in the backend for every read and mutation using predefined administrator, adult, restricted and viewer profiles, administrator-configurable household grants and explicit per-member exceptions, with deterministic precedence and current-policy checks. | +| household-identity-R3 | Suspension, role changes and unlinking MUST revoke effective access without erasing historical actor references. | +| household-identity-R4 | Identity flows MUST work in both deployment targets without trusting arbitrary client headers or exposing HA tokens to diagnostics. | +| household-identity-R5 | Administrators MUST retain control of configuring point values, verification, automation settings and privileged corrections; Domus authorization commands MUST preserve at least one active effective administrator. | +| household-identity-R6 | Members MUST control their locale and notification preferences and view participation without treating points as the sole fairness metric. | +| household-identity-R7 | Administrator mapping MUST support all_ha_administrators by default, setup_administrator and selected_ha_user alternatives, prove HA identity/administrator status where required and preserve last-administrator/recovery safety without granting privilege from browser arrival order or caller-supplied identity. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +Member(id, display_name, avatar_reference, ha_user_id, optional person_entity_id, role, active, preferences, revision). The HA user association is unique within the household. A person association supplies profile/presence only. Membership can be invited -> linked -> active -> suspended -> archived; unlinking immediately removes access without deleting historical authorship. + +The owner confirmed predefined role profiles with administrator-adjustable household permissions and per-member exceptions. RoleProfile retains the base role, explicit grants/denials and version; a MemberPermissionOverride retains permission, allow/deny, actor, reason and revision. Within configurable permissions, an explicit member override takes precedence over the household profile, which takes precedence over the predefined default; contradictory entries at the same level are rejected, with denial as the safe result for unresolved conflicts. Identity, household scope, installation limits and domain invariants remain hard constraints. Granting one action to a restricted member does not make that performer an adult or bypass required adult verification. Only an authorized administrator edits this policy; ordinary members cannot edit their own authority. Changes invalidate effective-permission caches and are rechecked at command commit and protected-result lookup. Snapshotted policy revisions explain past operations but cannot authorize a revoked grant. + +AdministratorMappingPolicy is configured explicitly during setup and may later be changed through an authorized audited command. The owner requested all three modes, with all_ha_administrators as the default. In that mode, each authenticated, authoritatively verified HA administrator receives the inherited Domus administrator role; other HA users do not. setup_administrator initially grants Domus administration only to the verified HA administrator who completes setup. selected_ha_user grants it initially to the explicitly selected active HA user, chosen by the verified HA administrator configuring the installation. Subsequent explicit Domus role assignments remain audited; alternate modes do not automatically elevate every other HA administrator. Continuous inheritance of current HA administrator status applies to all_ha_administrators; the alternatives designate the recorded setup identity or selected active HA account, and the selected account need not itself be an HA administrator. + +Initial configuration requires an explicit setup action by a proven HA administrator. Merely loading the page does not create a household or grant privilege. The default mode may link/activate a proven HA administrator according to the selected mapping policy after setup; ordinary unlinked users still need authorized membership activation. An inherited administrator grant retains its HA source and is removed when that source is no longer valid or the mapping changes; any independent explicit grant is evaluated separately. A profile/member edit cannot silently demote a currently inherited administrator role: change the authorized mapping or its HA source. Mapping never bypasses suspension, known revocation or technical-principal boundaries. A transport credential, person entity or submitted is_admin flag is not proof of a human HA administrator. + +The owner confirmed on 2026-10-29 that adult performers need no completion verification by default and restricted performers require approval by an authorized adult. Administrator control of verification configuration is separate from permission to approve a restricted member's completion. The effective policy follows actual performers; an adult submitting the record does not silently turn restricted work into adult work. Explicit overrides remain administrator-controlled and audited. + +### 6.2 States and alternatives + +Ordinary unlinked membership cannot participate; linked accounts become active after administrator assignment, with verified administrator mapping as the explicit exception above. Suspended users retain historical attribution but cannot access protected reads or commands. Domus role, profile, mapping and suspension commands cannot remove the last active effective administrator. HA can independently revoke or remove accounts; Domus must then remove invalid inherited access and surface authenticated recovery rather than keep stale privilege or give the next arbitrary browser administration. The supported recovery procedure remains an engineering/security gate. + +Authorization applies to operation lookup and duplicate receipts as well as new writes. Replaying a once-authorized command does not bypass a later suspension or expose the old private result to another principal. Household role revocation is checked against current local authority before returning protected data; a snapshotted execution policy is not a permission grant. Implementing the selected initial administrator mapping and recovery after external HA account loss requires a reviewed authenticated procedure; never promote the first arbitrary browser session or silently substitute a shared administrator. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `default_member_role` | enum | restricted | adult, restricted or viewer for ordinary activation; verified administrator mapping is a separate explicit policy | household; assigned at activation | +| `administrator_mapping` | enum | all_ha_administrators | all_ha_administrators, setup_administrator, selected_ha_user; selected mode requires a verified active target | installation/household; versioned, audited; current HA source checked | +| `role_permissions` | typed permission map | predefined administrator/adult/restricted/viewer profiles | supported explicit allow/deny entries; administrator-controlled, cannot weaken hard constraints | household profile revision | +| `member_permission_overrides` | typed permission map | none | supported explicit per-member exceptions; current administrator authorization and audit required | member policy revision; caches invalidated on change | +| `session_max_minutes` | integer | 60 | 5..240; revocation checked on each command | installation; bounded server session | +| `locale` | enum | browser preference | en or es, then en fallback | member; persisted | +| `person_entity_id` | optional entity reference | none | person domain only; duplicate mapping rejected | member; persisted | + +Administrator-owned member exceptions are part of the household authorization policy, not a self-service preference. They may change supported profile grants within hard constraints; ordinary member locale/notification settings never expand authority. + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: all_ha_administrators supplies inherited administration and an ordinary participant receives the restricted profile. Meaningful alternative: setup_administrator limits inherited initial administration to the installer, while an authorized member exception adjusts one supported action without changing identity or domain invariants. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +AuthenticatePrincipal and AuthorizeHouseholdAction are separate use cases. Authentication adapters verify HA identity; MemberRepository maps it to permissions. The application receives a trusted Principal, not an arbitrary member_id as identity. No local passwords or PINs are introduced. A technical HA service principal never inherits an adult role from a caller-supplied field. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Checking your Home Assistant account. No action required. | +| Action required | Your account is authenticated but is not linked to this household. Ask a household administrator to grant access. | +| Blocked | Your household access is suspended. No changes were saved. Contact an administrator. | +| Partial | The member was updated, but their optional person entity is unavailable. Account access remains linked. | +| Complete | Account linked. Your household role is Restricted member. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 30 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain and configuration | 6 | two members linked to one HA user; an adult creating an ordinary household task; removal of the last active administrator | +| Security and privacy | 9 | only a person entity ID; a viewer calling task completion directly; a restricted member reading another member's private preferences | +| Adapters and identity | 2 | a valid HA user authentication; an archived account | +| State and concurrency | 6 | a suspended member's existing session; concurrent reassignment and a role downgrade; a concurrent verification-policy change | +| Deployment and contracts | 3 | a forged identity header on standalone HTTP; a verified HA session through Ingress | +| UI and accessibility | 2 | Spanish member preferences; notification opt-out | +| Integration and recovery | 2 | differing task durations and equal points | +| **Total** | **30** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| household-identity-C01 | Domain and configuration | household-identity-R1 | Given two members linked to one HA user, the second association is rejected. | +| household-identity-C02 | Security and privacy | household-identity-R1 | Given only a person entity ID, a request cannot authenticate. | +| household-identity-C03 | Adapters and identity | household-identity-R1 | Given a valid HA user authentication, the corresponding active member is resolved without matching display names. | +| household-identity-C04 | Security and privacy | household-identity-R2 | Given a default viewer without task-completion permission calling completion directly, the backend denies it and preserves the task. | +| household-identity-C05 | Security and privacy | household-identity-R2 | Given a restricted member reading another member's private preferences, the backend denies the request. | +| household-identity-C06 | Domain and configuration | household-identity-R2 | Given an adult creating an ordinary household task, the role matrix permits it and records the actor. | +| household-identity-C07 | State and concurrency | household-identity-R3 | Given a suspended member's existing session, the next command is denied. | +| household-identity-C08 | State and concurrency | household-identity-R3 | Given concurrent reassignment and a role downgrade, authorization is checked at the command transaction boundary. | +| household-identity-C09 | Adapters and identity | household-identity-R3 | Given an archived account, historical task and ledger views retain its stable actor reference. | +| household-identity-C10 | Deployment and contracts | household-identity-R4 | Given a forged identity header on standalone HTTP, authentication fails. | +| household-identity-C11 | Deployment and contracts | household-identity-R4 | Given a verified HA session through Ingress, the correct user is resolved without a shared administrator fallback. | +| household-identity-C12 | Security and privacy | household-identity-R4 | Given expired upstream authorization, token renewal fails closed and diagnostics omit token material. | +| household-identity-C13 | Domain and configuration | household-identity-R5 | Given removal of the last active administrator, validation rejects the command. | +| household-identity-C14 | Security and privacy | household-identity-R5 | Given a restricted member editing task point values, the backend denies the request. | +| household-identity-C15 | State and concurrency | household-identity-R5 | Given a concurrent verification-policy change, completion uses the persisted policy revision and returns a conflict if stale. | +| household-identity-C16 | UI and accessibility | household-identity-R6 | Given Spanish member preferences, navigation and notification text use Spanish with English fallback for missing keys. | +| household-identity-C17 | UI and accessibility | household-identity-R6 | Given notification opt-out, routine participation summaries are suppressed. | +| household-identity-C18 | Integration and recovery | household-identity-R6 | Given differing task durations and equal points, participation reports show effort and counts alongside points. | +| household-identity-C19 | Security and privacy | household-identity-R2, household-identity-R3 | Given an operation committed before the member was suspended, replay or lookup after suspension returns no protected result and cannot invoke the old privilege. | +| household-identity-C20 | Security and privacy | household-identity-R1, household-identity-R2 | Given an unlinked authenticated user arriving before household setup is finished, access does not become administrator merely because that browser connected first. | +| household-identity-C21 | Deployment and contracts | household-identity-R1, household-identity-R7 | Given default all_ha_administrators, an authenticated proven HA administrator receives inherited Domus administration while an ordinary HA user or technical transport credential does not. | +| household-identity-C22 | Domain and configuration | household-identity-R7 | Given setup_administrator, the proven HA administrator explicitly completing setup receives the initial role and a different HA administrator is not automatically elevated by that alternate mapping. | +| household-identity-C23 | Security and privacy | household-identity-R1, household-identity-R7 | Given selected_ha_user, only the verified active selected account receives initial administration; caller-supplied names, forged flags or an unverified target cannot complete setup. | +| household-identity-C24 | State and concurrency | household-identity-R3, household-identity-R7 | Given an authorized mapping change, inherited grants are reevaluated with their source and independent explicit grants stay distinct; an old mapping revision cannot authorize a later command. | +| household-identity-C25 | Integration and recovery | household-identity-R3, household-identity-R7 | Given all_ha_administrators with externally revoked HA administrator status or a removed final account, the invalid inherited grant is not retained and authenticated recovery is required rather than promoting the next browser. | +| household-identity-C26 | State and concurrency | household-identity-R2, household-identity-R3 | Given a household profile allowance and an explicit member denial saved during an active session, the denial takes precedence and a stale cached allowance cannot authorize the next command. | +| household-identity-C27 | Security and privacy | household-identity-R2, household-identity-R5 | Given an unauthorized self-grant or an allowed action aimed at another household, the backend rejects the policy/command and neither profile customization nor member exceptions bypass scope or adult-verification invariants. | +| household-identity-C28 | State and concurrency | household-identity-R5, household-identity-R7 | Given a mapping/profile/suspension change that would remove the final active effective administrator, the Domus transaction rejects it with current policy intact, including concurrent changes. | +| household-identity-C29 | Domain and configuration | household-identity-R2 | Given a household profile denial for a supported ordinary action and an authorized explicit member allowance, the backend permits only that action within scope while unrelated denied actions remain denied. | +| household-identity-C30 | Domain and configuration | household-identity-R2 | Given contradictory allow/deny entries for the same permission at the same precedence level, saving rejects the policy with prior effective permissions retained instead of resolving it to an accidental grant. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/household-identity.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| household-identity-R1 | household-identity-C01, household-identity-C02, household-identity-C03, household-identity-C20, household-identity-C21, household-identity-C23 | +| household-identity-R2 | household-identity-C04, household-identity-C05, household-identity-C06, household-identity-C19, household-identity-C20, household-identity-C26, household-identity-C27, household-identity-C29, household-identity-C30 | +| household-identity-R3 | household-identity-C07, household-identity-C08, household-identity-C09, household-identity-C19, household-identity-C24, household-identity-C25, household-identity-C26 | +| household-identity-R4 | household-identity-C10, household-identity-C11, household-identity-C12 | +| household-identity-R5 | household-identity-C13, household-identity-C14, household-identity-C15, household-identity-C27, household-identity-C28 | +| household-identity-R6 | household-identity-C16, household-identity-C17, household-identity-C18 | +| household-identity-R7 | household-identity-C21, household-identity-C22, household-identity-C23, household-identity-C24, household-identity-C25, household-identity-C28 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/household-inventory.md b/specs/household-inventory.md new file mode 100644 index 0000000..770c763 --- /dev/null +++ b/specs/household-inventory.md @@ -0,0 +1,314 @@ +# Product catalog, pantry stock and replenishment + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: household-inventory +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: The household knows what is available, where it is stored and what needs replenishment through a local product catalog and an immutable stock movement ledger. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Unit/package policy; reservation/replenishment review; barcode library/device evidence; external lookup provider feasibility, terms and response contract. The owner confirmed barcode scope, adjustable material recording and pending regularization rather than negative stock for task material shortfalls on 2026-10-29. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +The household knows what is available, where it is stored and what needs replenishment through a local product catalog and an immutable stock movement ledger. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +A large pantry contains long-life supplies in different packages and storage places. Editing a quantity directly loses receipt, consumption and adjustment history. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Household member; receiver; authorized stock administrator; replenishment policy. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| household-inventory-R1 | Product identity, package presentation and base measurement unit MUST be distinct and conversions exact. | +| household-inventory-R2 | Every stock change MUST be an immutable, attributable movement; corrections append compensating records rather than deleting history. | +| household-inventory-R3 | Stock and reservations MUST prevent accidental negative availability and handle concurrent consumption and balanced transfers; insufficient stock in an already-performed task MUST retain a pending consumption intent without inventing a stock movement or blocking completion. | +| household-inventory-R4 | Replenishment MUST use minimum/target policies and stable source identities without duplicating task material demand or manual shopping extras. | +| household-inventory-R5 | Receipt integration MUST post only received quantities once and preserve partial-receipt and retry history. | +| household-inventory-R6 | Locations, optional lots and expiry information MUST remain queryable without inferring that expired stock disappeared. | +| household-inventory-R7 | Barcode entry MUST support camera scanning, manual fallback, local validation/catalog search and optional configured Internet product lookup, with explicit camera permission, safe candidate validation and usable local operation when lookup is absent or fails. | +| household-inventory-R8 | Inventory permissions, inactive products, backup/restore and pagination MUST preserve ledger integrity and household privacy. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +Product owns identity, brand, category, barcode references, description, optional image, active flag and base unit. PackagePresentation owns pack count and conversion to that base unit; six 1-litre cartons may be six pieces or six litres according to a fixed product unit, never both without explicit conversion. Location, optional Lot(expiry, received_at), StockMovement, Reservation and ReplenishmentPolicy are separate records. Quantity uses exact decimal arithmetic. Transfer has balanced source/destination legs in one transaction. Availability equals physical stock minus active reservations. Consumption is explicit; estimates and predictions are future suggestions, not silent stock decrements. + +Task completion may submit explicitly reviewed actual material quantities in the same user action, as confirmed by the owner. Inventory processes those linked intents through the same consumption rules as a standalone movement; planned requirements are not proof of usage. Each intent has a stable completion-cycle/line identity and operation outcome. Consuming a task's own reserved material converts that reservation to consumed while decrementing physical stock in the same transaction, so availability is not charged twice. Other tasks' reservations cannot be stolen silently. A task reopen or verification rejection never adds a physical return: a real return/correction is a distinct authorized movement with an explicit reason. + +If a submitted material line lacks sufficient usable stock, save a pending_regularization consumption intent while the performed task completes, as confirmed by the owner. The intent is not a StockMovement and does not lower physical or available stock below zero. Keep its requested quantity, location, completion-cycle/line identity, actor and shortage reason visible. The affected quantity is labeled as recorded stock with a discrepancy requiring review, not silently presented as a verified physical count. No partial decrement within that line is silently substituted for the confirmed quantity. Authorized regularization reviews missing receipts, actual counts or erroneous usage, then posts a validated movement or records an explained correction/dismissal of the intent. A restock event alone does not settle it. Settlement, movement and operation receipt commit together; retries cannot post the line twice. A pending intent is not another reservation or purchasing demand, so it cannot double-count an existing material/replenishment source. Explicit zero usage is not_used and creates no stock movement. + +The owner confirmed camera scan and manual entry with optional Internet product lookup on 2026-10-29, closing the missing barcode-scope decision from the truncated attachment. Local catalog lookup runs first. An administrator may configure an external provider; unknown-code lookup is on demand by default. Only the barcode and required provider authentication leave the server boundary, never camera frames, household identity or stock history. Provider responses are untrusted candidates with source/provenance; users review a candidate before importing or matching a product/presentation. No provider is selected or advertised as available yet; feasibility, terms, rate limits and household-product coverage remain adapter review gates. + +### 6.2 States and alternatives + +Product active -> inactive without deleting history. Reservation active -> consumed/released. Consumption intent -> posted or pending_regularization -> posted/corrected/dismissed with retained reason. Receipt -> posted movement; correction -> compensating movement. Low-stock demand open -> updated -> satisfied, retaining a stable policy/source identity. Optional lot expiration warns but does not silently remove stock. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `base_unit` | unit code | piece | piece, gram, millilitre or explicitly supported compatible unit; immutable after movements without migration | product; persisted | +| `minimum_stock` | decimal | 0 | nonnegative, <= target_stock | product/location policy; versioned | +| `target_stock` | decimal | 0 | nonnegative, >= minimum_stock | product/location policy; versioned | +| `expiration_tracking` | boolean | false | requires optional lot dates when enabled; no fabricated date | product; persisted | +| `negative_stock_policy` | enum | reject | reject initially; corrections require a reason | household invariant | +| `external_product_lookup` | enum | off until a provider is configured, then on_demand | off, on_demand or explicit automatic_unknown; administrator-controlled provider setup | household preference; lookup operation snapshots provider/policy version | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: piece-based stock with local product search, no expiry tracking and no external lookup. Meaningful alternative: a product enables lot dates and an administrator configures on-demand lookup, without changing its established base unit or ledger history. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +RecordMovement, TransferStock, ReserveMaterials, CorrectStock and EvaluateReplenishment use StockLedger, ProductRepository and DemandPort. Pure quantity and allocation policies validate units. Ledger movements and reservations share transactional consistency; replenishment uses deterministic source IDs and outbox delivery. Barcode scanning is a client adapter with manual entry fallback. Optional Internet lookup implements ProductLookupPort with bounded requests, candidate schemas, provenance, caching and safe error mapping; neither domain code nor UI primitives import provider SDKs. Remote failure never blocks manual/local catalog workflows. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Recording stock. No action required. | +| Action required | This pack has no unit conversion. Choose its package format before receiving it. | +| Blocked | Only one unit is available. Nothing was consumed. Review stock or release a reservation. | +| Partial | Stock is saved. Its shopping replenishment requirement is waiting to refresh. | +| Complete | Six litres added to Pantry. View the receipt and movement. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 35 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain and configuration | 9 | a six-pack of one-litre cartons in a litre-based product; incompatible kilogram and piece units without conversion; a product with movements | +| Adapters and persistence | 4 | an adjustment with a reason; expiration tracking disabled | +| Security and privacy | 5 | deletion of an existing movement; scanning without external lookup configured; a viewer trying stock correction | +| State and concurrency | 6 | a corrected receipt; simultaneous consumption of the last unit; a stock transfer failure between its two legs | +| Integration and recovery | 8 | task-reserved stock; a manual extra demand; four of six purchased units received | +| UI and accessibility | 2 | an approaching expiry; denied camera permission | +| Deployment and contracts | 1 | an inactive product or paginated stock query | +| **Total** | **35** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| household-inventory-C01 | Domain and configuration | household-inventory-R1 | Given a six-pack of one-litre cartons in a litre-based product, receipt adds exactly six litres. | +| household-inventory-C02 | Domain and configuration | household-inventory-R1 | Given incompatible kilogram and piece units without conversion, validation rejects the movement. | +| household-inventory-C03 | Domain and configuration | household-inventory-R1 | Given a product with movements, changing its base unit requires an explicit migration instead of reinterpreting stock. | +| household-inventory-C04 | Adapters and persistence | household-inventory-R2 | Given an adjustment with a reason, the ledger exposes actor, source, timestamp and signed amount. | +| household-inventory-C05 | Security and privacy | household-inventory-R2 | Given deletion of an existing movement, the backend denies it and offers a correction path. | +| household-inventory-C06 | State and concurrency | household-inventory-R2 | Given a corrected receipt, both the original movement and linked compensation remain. | +| household-inventory-C07 | State and concurrency | household-inventory-R3 | Given simultaneous consumption of the last unit, only one transaction succeeds. | +| household-inventory-C08 | State and concurrency | household-inventory-R3 | Given a stock transfer failure between its two legs, neither location balance changes. | +| household-inventory-C09 | Domain and configuration | household-inventory-R3 | Given a reservation larger than available stock, the material shortfall is explicit rather than negative availability. | +| household-inventory-C10 | Domain and configuration | household-inventory-R4 | Given a repeated low-stock evaluation, the same source demand is updated rather than duplicated. | +| household-inventory-C11 | Integration and recovery | household-inventory-R4 | Given task-reserved stock, replenishment calculates availability once and does not add the same reservation twice. | +| household-inventory-C12 | Integration and recovery | household-inventory-R4 | Given a manual extra demand, replenishment changes do not delete or reduce that user intent. | +| household-inventory-C13 | State and concurrency | household-inventory-R5 | Given duplicate receipt messages, one inventory movement exists for each receipt line. | +| household-inventory-C14 | Integration and recovery | household-inventory-R5 | Given four of six purchased units received, stock increases by four only. | +| household-inventory-C15 | Integration and recovery | household-inventory-R5 | Given receipt saved before posting failure, retry posts once and marks that receipt line complete. | +| household-inventory-C16 | Domain and configuration | household-inventory-R6 | Given a product in two locations and two lots, quantities reconcile to the product total. | +| household-inventory-C17 | UI and accessibility | household-inventory-R6 | Given an approaching expiry, the UI shows the lot and date without deleting its quantity. | +| household-inventory-C18 | Adapters and persistence | household-inventory-R6 | Given expiration tracking disabled, a receipt requires no invented expiry date. | +| household-inventory-C19 | UI and accessibility | household-inventory-R7 | Given denied camera permission, the scan view offers manual barcode and product entry. | +| household-inventory-C20 | Domain and configuration | household-inventory-R7 | Given a malformed supported GTIN, local check-digit validation identifies the error. | +| household-inventory-C21 | Security and privacy | household-inventory-R7 | Given scanning without external lookup configured, no image or barcode leaves the installation. | +| household-inventory-C22 | Security and privacy | household-inventory-R8 | Given a default viewer without a stock-correction grant, authorization rejects the correction. | +| household-inventory-C23 | Integration and recovery | household-inventory-R8 | Given a restored backup, physical stock and reservations reconcile to the original ledger. | +| household-inventory-C24 | Deployment and contracts | household-inventory-R8 | Given an inactive product or paginated stock query, history remains available and result bounds are enforced. | +| household-inventory-C25 | Adapters and persistence | household-inventory-R7 | Given an unknown local barcode and an enabled on-demand external lookup, the adapter sends only the barcode and required provider authentication and returns a bounded candidate with source provenance. | +| household-inventory-C26 | Integration and recovery | household-inventory-R7 | Given a provider timeout or rate limit, lookup reports unavailability while manual product creation and local search remain usable without a stock mutation. | +| household-inventory-C27 | Security and privacy | household-inventory-R7 | Given hostile, oversized or incompatible provider fields, validation rejects the candidate and no script, private URL fetch or unreviewed catalog overwrite occurs. | +| household-inventory-C28 | Security and privacy | household-inventory-R7 | Given external lookup off or no provider configured, camera/manual scanning uses local data only and no barcode, frame or household information is sent externally. | +| household-inventory-C29 | State and concurrency | household-inventory-R2, household-inventory-R3 | Given two physical units and a two-unit reservation for the completing task, recording one actual unit leaves one physical unit and one active reserved unit; releasing the unused reservation makes one available, without charging the used unit twice. | +| household-inventory-C30 | Integration and recovery | household-inventory-R2 | Given a task material intent already posted, replaying the completion or the linked inventory command returns that movement once and does not decrement stock again. | +| household-inventory-C31 | Domain and configuration | household-inventory-R2 | Given task reopening or rejected verification after material consumption, physical stock does not increase; a confirmed real return appends its own linked movement. | +| household-inventory-C32 | Integration and recovery | household-inventory-R2, household-inventory-R3 | Given a task consumption line larger than usable stock, save a pending intent and its source while the task completes, with no negative stock, partial hidden decrement or fabricated movement. | +| household-inventory-C33 | State and concurrency | household-inventory-R2, household-inventory-R3 | Given two concurrent authorized settlements of one pending intent, at most one validated movement posts and both responses resolve the same retained intent. | +| household-inventory-C34 | Domain and configuration | household-inventory-R3, household-inventory-R4 | Given restocking while an earlier task consumption is pending, the original intent stays visible for review, stock does not decrease automatically and no duplicate material demand is created. | +| household-inventory-C35 | Adapters and persistence | household-inventory-R2 | Given explicit zero usage on a task material line, the linked result is not_used, no stock movement is fabricated and replay preserves the same factual result. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/household-inventory.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| household-inventory-R1 | household-inventory-C01, household-inventory-C02, household-inventory-C03 | +| household-inventory-R2 | household-inventory-C04, household-inventory-C05, household-inventory-C06, household-inventory-C29, household-inventory-C30, household-inventory-C31, household-inventory-C32, household-inventory-C33, household-inventory-C35 | +| household-inventory-R3 | household-inventory-C07, household-inventory-C08, household-inventory-C09, household-inventory-C29, household-inventory-C32, household-inventory-C33, household-inventory-C34 | +| household-inventory-R4 | household-inventory-C10, household-inventory-C11, household-inventory-C12, household-inventory-C34 | +| household-inventory-R5 | household-inventory-C13, household-inventory-C14, household-inventory-C15 | +| household-inventory-R6 | household-inventory-C16, household-inventory-C17, household-inventory-C18 | +| household-inventory-R7 | household-inventory-C19, household-inventory-C20, household-inventory-C21, household-inventory-C25, household-inventory-C26, household-inventory-C27, household-inventory-C28 | +| household-inventory-R8 | household-inventory-C22, household-inventory-C23, household-inventory-C24 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/household-tasks.md b/specs/household-tasks.md new file mode 100644 index 0000000..16d4d32 --- /dev/null +++ b/specs/household-tasks.md @@ -0,0 +1,323 @@ +# Task definitions, occurrences and household execution + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: household-tasks +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Members create and perform household responsibilities with explicit assignments, actual performers and history. A recurring definition survives completion of each individual occurrence. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed role/override review; first-release advanced task-type matrix. The owner confirmed role-default verification, material-completion handling and preservation of completed downstream work/points when its prerequisite is reopened on 2026-10-29. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Members create and perform household responsibilities with explicit assignments, actual performers and history. A recurring definition survives completion of each individual occurrence. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +A title and completed flag cannot represent recurring or collaborative household work, material requirements, verification and auditable corrections. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Creator; assignee; actual performer; authorized verifier; household administrator. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| household-tasks-R1 | A task definition and occurrence MUST have separate stable identities; completing an occurrence never destroys its definition. | +| household-tasks-R2 | Every transition MUST enforce the explicit state machine, expected revision, dependencies and completion requirements; reopening a prerequisite MUST retain already-completed downstream work and points with a visible review condition, without automatic cascading reopening. | +| household-tasks-R3 | Assignment MUST distinguish planned assignees, completion actor and actual performers and support unassigned pools, reassignment and collaboration. | +| household-tasks-R4 | Completion and reopening MUST be idempotent and emit uniquely identified business events without duplicate downstream rewards. | +| household-tasks-R5 | Verification MUST default to none for adult performers and authorized-adult approval for restricted performers, prevent unauthorized approval and defer points until any required verification succeeds. | +| household-tasks-R6 | Task history MUST retain creation, assignment, transitions, completion, reopening, schedule changes and related automation actors. | +| household-tasks-R7 | Task creation MUST support a minimal title-only path and optional advanced fields, categories, subtasks, materials and entity links. | +| household-tasks-R8 | Every task command MUST enforce household scope and role permissions and return actionable validation, conflict and recovery results. | +| household-tasks-R9 | Material recording MUST default to an adjustable review in the completion form, configurable per task; one explicit submission MUST retain linked outcomes without duplicate stock changes, insufficient stock MUST leave completed work saved with consumption pending regularization rather than negative stock, and reopening MUST NOT imply a physical material return. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +TaskDefinition owns title, description, configurable category, tags, priority, estimated duration, complexity, inconvenience, point policy, recurrence reference, material requirements, optional HA entity references, completion requirements and version. TaskOccurrence owns definition snapshot, scheduled start, due date or instant, assignees, participants, state, actual performers, completion actor/time and history. Only title is required for ordinary creation; advanced properties remain optional. Dependencies form an acyclic graph scoped to the household. Subtasks are explicit child occurrences; completion policy is all-required by default. + +The owner confirmed adjustable material quantities in the completion form, submitted with the task completion, configurable per task. The default review shows planned quantities, units and storage targets; the member explicitly confirms actual usage, including zero for an unused material. A zero line is retained as not_used without fabricating a zero-quantity stock movement. Merely displaying the form or marking an unrelated task complete never consumes stock. A separate-recording task option retains an explicit later inventory action. The effective mode and submitted lines are snapshotted; the server validates stock permissions, product/unit/location compatibility and stable line identities rather than trusting the client preview. + +One application orchestration accepts the completion and explicit material intents under the same operation receipt. Inventory still owns consumption rules and movement records; this is one user submission, not a second implementation of inventory policy in Tasks. Stable child identities link each consumption line to its completion cycle and deduplicate whole-request or line retries. Invalid input or unauthorized intents fail admission before any new completion or movement; a genuine stock shortfall is a recoverable business outcome rather than invalid identity or permission. + +The owner confirmed that insufficient stock must not block recording work already performed. Save the completion and the affected intent as pending_regularization, with submitted quantity, source and safe reason; do not post an impossible movement or negative stock. Report each material line separately, including any successful lines, without presenting pending ones as consumed. Existing performer-verification and point rules still apply independently, and recurrence uses actual completion. An authorized member reviews actual inventory facts and explicitly resolves the pending intent; purchasing new stock alone does not silently post an old consumption. Settlement retains the same linked intent identity, handles races/replays once and leaves a visible audit trail. + +### 6.2 States and alternatives + +Definition: draft -> active <-> paused -> archived. Occurrence: draft -> available <-> assigned -> in_progress; available/assigned/in_progress -> blocked or completed; blocked -> available or assigned; active states -> cancelled or skipped. Reopen completed -> assigned if assignees exist, otherwise available. Verification is a separate pending/approved/rejected decision; pending completion is displayed as awaiting verification and awards no points. + +The owner confirmed the role defaults on 2026-10-29. Without an explicit administrator-controlled task override, adult performers need no verification and any restricted actual performer requires approval by an authorized adult. Determine that policy from the actual performers, not merely the authenticated submitter: an adult recording a restricted member's work does not silently bypass the approval step. Restricted members cannot set their own policy to none or approve their own completion. The effective policy and its revision are snapshotted with completion. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +Each accepted completion has a stable completion-cycle ID. Reopening closes that cycle; a genuine later completion gets a new ID. A delayed completion or approval from the closed cycle cannot create a new award or re-complete the occurrence. Reopening does not prove that consumed supplies physically returned: inventory remains unchanged unless an authorized, separately confirmed return/correction movement records actual facts. Rejection of verification likewise cannot fabricate returned stock. + +The owner confirmed that reopening a prerequisite does not reopen its completed dependents or reverse their points. Keep each dependent's completed state, performer/time, accepted completion cycle, points, materials and recurrence facts. Record a separate dependency_attention condition naming the reopened prerequisite and request review. This condition is not a new completion, reversal or forced stock return. An authorized review can resolve the dependency through the normal prerequisite or dependency-edit commands, with actor/reason/history; it cannot erase real downstream work. Unstarted or unfinished dependents continue to enforce the ordinary prerequisite gate before completion. Replayed or stale dependency events are compared with current prerequisite revision so they cannot duplicate notices or reintroduce a resolved warning. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `default_priority` | enum | normal | low, normal, high, urgent | household; occurrence snapshots | +| `completion_verification` | enum | role_default | role_default: adults none, restricted performers authorized_adult; explicit none/authorized_adult overrides require administrator permission | definition; effective role policy and revision snapshotted at completion | +| `dependency_policy` | enum | all_required | all_required only initially; cycles rejected | definition; versioned | +| `category` | string reference | General | active household category; optional | definition; persisted | +| `material_recording` | enum | review_on_completion | review_on_completion or separate_recording; explicit actual quantities, no silent consumption | definition; mode and material lines snapshotted for each completion | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: title-only creation, role-default verification and adjustable material review on completion when materials exist. Meaningful alternative: a task records consumption separately while preserving the same inventory permissions and receipts. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +CreateTask, ClaimTask, AssignTask, TransitionOccurrence, VerifyCompletion and ReopenOccurrence use TaskRepository, AuthorizationPolicy, UnitOfWork and EventOutbox. A completion orchestration delegates explicit material intents to the Inventory application port with stable child command identities. Domain transition and dependency policies are pure. A completion emits a durable event for points and recurrence. HA and HTTP adapters cannot implement alternate completion semantics. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Saving “Clean the bathrooms”. Keep this screen open. | +| Action required | “Clean the bathrooms” needs a performer. Choose who completed the work. | +| Blocked | This task changed while you were editing it. Your draft is retained. Review the latest version. | +| Partial | Task completed. The points summary is refreshing; the completion is saved. View history. | +| Complete | Completed by Alex today at 10:30. 12 points awarded. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 38 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain and configuration | 8 | an active recurring definition; a blocked prerequisite; a cyclic dependency or an incomplete required subtask | +| Adapters and persistence | 2 | a later definition edit; assignment | +| Integration and recovery | 8 | a one-time title-only task; a reopened completed task; pending verification | +| State and concurrency | 7 | two concurrent transitions with the same revision; two simultaneous claims on a single-assignee task; duplicate completion commands | +| UI and accessibility | 7 | a collaborative task; rejected verification; title-only entry on a narrow screen | +| Security and privacy | 6 | a verifier policy requiring another member; an arbitrary history deletion request from a member; a foreign-household task ID | +| **Total** | **38** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| household-tasks-C01 | Domain and configuration | household-tasks-R1 | Given an active recurring definition, completing Saturday's occurrence leaves the definition active. | +| household-tasks-C02 | Adapters and persistence | household-tasks-R1 | Given a later definition edit, a completed occurrence retains its original snapshot. | +| household-tasks-C03 | Integration and recovery | household-tasks-R1 | Given a one-time title-only task, exactly one occurrence is available. | +| household-tasks-C04 | Domain and configuration | household-tasks-R2 | Given a blocked prerequisite, completing its dependent task is rejected with the blocking task link. | +| household-tasks-C05 | State and concurrency | household-tasks-R2 | Given two concurrent transitions with the same revision, only one succeeds and the other returns conflict. | +| household-tasks-C06 | Domain and configuration | household-tasks-R2 | Given a cyclic dependency or an incomplete required subtask, validation rejects completion. | +| household-tasks-C07 | State and concurrency | household-tasks-R3 | Given two simultaneous claims on a single-assignee task, one claim wins without silent reassignment. | +| household-tasks-C08 | Domain and configuration | household-tasks-R3 | Given a reassigned task performed by another authorized member, history preserves both assignment and actual performer. | +| household-tasks-C09 | UI and accessibility | household-tasks-R3 | Given a collaborative task, the completion form names participants before confirmation. | +| household-tasks-C10 | State and concurrency | household-tasks-R4 | Given duplicate completion commands, one completion event exists. | +| household-tasks-C11 | Integration and recovery | household-tasks-R4 | Given a reopened completed task, the downstream compensation references its original completion. | +| household-tasks-C12 | State and concurrency | household-tasks-R4 | Given an old completion retry after reopening, the receipt returns the original result without completing again. | +| household-tasks-C13 | Security and privacy | household-tasks-R5 | Given a verifier policy requiring another member, self-verification is denied. | +| household-tasks-C14 | Integration and recovery | household-tasks-R5 | Given pending verification, no points appear until an authorized approval event is committed. | +| household-tasks-C15 | UI and accessibility | household-tasks-R5 | Given rejected verification, the task displays the reason and can be resumed without a false award. | +| household-tasks-C16 | Adapters and persistence | household-tasks-R6 | Given assignment, completion and reopening, activity shows actor, time and changes in stable order. | +| household-tasks-C17 | Integration and recovery | household-tasks-R6 | Given an automation-created occurrence, history preserves the technical origin and correlation. | +| household-tasks-C18 | Security and privacy | household-tasks-R6 | Given an arbitrary history deletion request from a member, the backend rejects it. | +| household-tasks-C19 | UI and accessibility | household-tasks-R7 | Given title-only entry on a narrow screen, the task can be saved without opening advanced fields. | +| household-tasks-C20 | Domain and configuration | household-tasks-R7, household-tasks-R9 | Given review_on_completion with two planned units, the member confirms one actual unit in the same submission; the task result links exactly one one-unit consumption rather than decrementing the estimate. | +| household-tasks-C21 | Domain and configuration | household-tasks-R7 | Given an invalid entity or category reference, validation identifies that field without losing the draft. | +| household-tasks-C22 | Security and privacy | household-tasks-R8 | Given a foreign-household task ID, the request cannot read or change it. | +| household-tasks-C23 | UI and accessibility | household-tasks-R8 | Given a revision conflict, the form preserves entered values and offers reload/review. | +| household-tasks-C24 | Integration and recovery | household-tasks-R8 | Given a lost completion response after commit, retry shows the committed result and history once. | +| household-tasks-C25 | Domain and configuration | household-tasks-R5 | Given only adult performers and no explicit verification override, completion is accepted without an approval step and becomes eligible for one points allocation. | +| household-tasks-C26 | Security and privacy | household-tasks-R5 | Given a restricted actual performer with no policy override, even an adult submitting completion leaves it awaiting authorized-adult approval and awards no points yet. | +| household-tasks-C27 | Security and privacy | household-tasks-R8 | Given a restricted member setting verification to none, backend authorization rejects the override and retains the effective adult-approval policy. | +| household-tasks-C28 | UI and accessibility | household-tasks-R9 | Given review_on_completion, opening the form changes no stock and a member can explicitly submit zero usage for an unused material with the completion. | +| household-tasks-C29 | State and concurrency | household-tasks-R4, household-tasks-R9 | Given a lost response after completion and material recording, replaying the original request returns the same completion and per-line outcomes without consuming twice. | +| household-tasks-C30 | Domain and configuration | household-tasks-R9 | Given separate_recording on a task, completion creates no stock movement and a later explicit inventory action can reference that completion. | +| household-tasks-C31 | Integration and recovery | household-tasks-R4, household-tasks-R9 | Given reopening after confirmed material consumption, task history and points compensation reference the original cycle while physical inventory stays consumed until an explicit factual return or correction. | +| household-tasks-C32 | Security and privacy | household-tasks-R8, household-tasks-R9 | Given a completion material line for another household or an unauthorized stock location, backend validation denies that intent with no unauthorized movement and retains actionable operation state. | +| household-tasks-C33 | State and concurrency | household-tasks-R4, household-tasks-R5 | Given reopening followed by a genuine new completion, delayed approval of the old cycle cannot approve or award the new cycle; identities and history remain distinct. | +| household-tasks-C34 | Integration and recovery | household-tasks-R4, household-tasks-R9 | Given work performed with insufficient material stock, submission saves one completion and a pending_regularization intent, creates no negative stock, and retains the same pending result on replay. | +| household-tasks-C35 | UI and accessibility | household-tasks-R5, household-tasks-R9 | Given a completed task with one posted material line and one shortfall, the result names the posted and pending quantities separately and shows verification/points independently rather than calling the whole submission failed. | +| household-tasks-C36 | Integration and recovery | household-tasks-R2, household-tasks-R4 | Given a completed dependent and its prerequisite being reopened, the dependent retains completion, points, materials and recurrence facts while a linked review condition appears; no automatic reopening or compensation chain occurs. | +| household-tasks-C37 | UI and accessibility | household-tasks-R2, household-tasks-R6 | Given dependency_attention on completed work, the UI retains its actual completion and points, names the changed prerequisite and offers an authorized review without presenting the work as unperformed. | +| household-tasks-C38 | State and concurrency | household-tasks-R2, household-tasks-R4 | Given reviewed dependency recovery followed by a delayed or repeated old reopen event, revision checks keep the resolved state and do not duplicate warnings, completions or awards. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/household-tasks.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| household-tasks-R1 | household-tasks-C01, household-tasks-C02, household-tasks-C03 | +| household-tasks-R2 | household-tasks-C04, household-tasks-C05, household-tasks-C06, household-tasks-C36, household-tasks-C37, household-tasks-C38 | +| household-tasks-R3 | household-tasks-C07, household-tasks-C08, household-tasks-C09 | +| household-tasks-R4 | household-tasks-C10, household-tasks-C11, household-tasks-C12, household-tasks-C29, household-tasks-C31, household-tasks-C33, household-tasks-C34, household-tasks-C36, household-tasks-C38 | +| household-tasks-R5 | household-tasks-C13, household-tasks-C14, household-tasks-C15, household-tasks-C25, household-tasks-C26, household-tasks-C33, household-tasks-C35 | +| household-tasks-R6 | household-tasks-C16, household-tasks-C17, household-tasks-C18, household-tasks-C37 | +| household-tasks-R7 | household-tasks-C19, household-tasks-C20, household-tasks-C21 | +| household-tasks-R8 | household-tasks-C22, household-tasks-C23, household-tasks-C24, household-tasks-C27, household-tasks-C32 | +| household-tasks-R9 | household-tasks-C20, household-tasks-C28, household-tasks-C29, household-tasks-C30, household-tasks-C31, household-tasks-C32, household-tasks-C34, household-tasks-C35 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/platform-foundation.md b/specs/platform-foundation.md new file mode 100644 index 0000000..f0f2c50 --- /dev/null +++ b/specs/platform-foundation.md @@ -0,0 +1,289 @@ +# Local application platform and persistence + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: platform-foundation +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: One local modular application serves the complete household product in both a Supervisor-managed App and standalone Docker from the first release. Home Assistant owns user authentication; Domus owns its business records. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Storage concurrency verification; supported Home Assistant release matrix; backup retention and restore targets. The owner selected Python/FastAPI, SQLite, one household per installation and a thin HA integration on 2026-10-29. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +One local modular application serves the complete household product in both a Supervisor-managed App and standalone Docker from the first release. Home Assistant owns user authentication; Domus owns its business records. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +Domus has no application runtime, database, or deployment artifact. The gateway demonstrates a useful application boundary but is not part of Domus deployment work. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Household administrator; authenticated member; installation operator. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| platform-foundation-R1 | Every deployment MUST retain household records through application restart and reject unsupported schema versions before writes. | +| platform-foundation-R2 | A command MUST atomically commit its business effects, receipt, audit reference and outbox, and replay an identical key without duplicate effects. | +| platform-foundation-R3 | Both Supervisor App and standalone Container MUST offer the same domain features from the first usable release. | +| platform-foundation-R4 | The application MUST remain useful without Internet, AI or an available gateway; unavailable HA-dependent operations show a precise degraded state. | +| platform-foundation-R5 | Backup and restore MUST preserve ledgers, schema and operation receipts and verify integrity before activation. | +| platform-foundation-R6 | Application boundaries MUST prevent domain imports of HA, HTTP, SQL and UI frameworks and keep secrets out of representations. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +Household, principal, command receipt, aggregate revision, audit record, outbox event, schema version and backup manifest. One household per installation is owner-confirmed; one active database writer remains an engineering proposal requiring concurrency evidence. Every record carries household identity. A command transaction commits its domain changes, command receipt and outbox together. Projections are rebuildable; business ledgers are not. + +Audit-display retention is distinct from command replay protection. Expiring routine activity/log data must not discard the receipt or compact replay guard needed to prevent a side-effecting command from running again. Any compaction retains command scope, payload digest and durable result reference, including closed completion cycles and per-line material identities. Backups include this evidence with the corresponding business state. Receipt lookup/replay still checks the current authenticated principal, household and permissions before revealing a result; possession of a guessed key is never authorization. + +### 6.2 States and alternatives + +Starting -> migrating -> ready; a migration error enters maintenance without serving writes. HA unavailable produces a degraded integration state while already authenticated local sessions may read cached household data until their bounded expiry. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `deployment_mode` | enum | supervisor | supervisor or standalone; explicit, no fallback | installation; restart | +| `household_timezone` | IANA zone | selected during setup | valid zone required; never assume UTC for local dates | household; commands snapshot version | +| `request_page_size` | integer | 50 | 1..200 | request; not persisted | +| `audit_retention_days` | integer | 365 | 30..3650; never deletes points or stock ledgers | installation; persisted | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: an explicit supervisor deployment with the household time zone selected at setup. Meaningful alternative: standalone uses the same domain contracts without assuming Supervisor or Ingress. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +Application commands depend on UnitOfWork, CommandReceiptStore, EventOutbox, Clock and BackupPort. SQLite is the owner-selected database, with migrations owned by infrastructure. FastAPI and HA integration adapters call the same use cases. Domain modules cannot import frameworks, SQL or HA. A single writer is the initial concurrency proposal; optimistic aggregate revisions bound races without distributed transactions. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Starting Domus. Your household data is being checked. No action required. | +| Action required | Setup needs a household time zone. Choose a time zone to continue. | +| Blocked | Domus cannot open this database version. Writes are paused. Restore a compatible application; your database is retained. | +| Partial | Your task was saved. Home Assistant projections are waiting to reconnect. View activity. | +| Complete | Domus is ready. Your household data is available. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 20 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain and configuration | 1 | an unknown schema version | +| Adapters and persistence | 3 | committed household data; a crash between domain SQL and outbox SQL; a consistent snapshot during writes | +| Integration and recovery | 5 | a failed migration; the same command fixtures; Internet and gateway outages | +| State and concurrency | 3 | a repeated command key and identical payload; a repeated key with a different payload; restoration of command receipts | +| Deployment and contracts | 4 | a Supervisor test installation; standalone Compose without Supervisor; a domain import of a concrete HTTP client | +| UI and accessibility | 1 | HA disconnection | +| Security and privacy | 3 | an expired session during HA outage; an exception containing a credential | +| **Total** | **20** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| platform-foundation-C01 | Domain and configuration | platform-foundation-R1 | Given an unknown schema version, startup refuses writes and explains the required compatible version. | +| platform-foundation-C02 | Adapters and persistence | platform-foundation-R1 | Given committed household data, a process restart returns the same IDs and revisions. | +| platform-foundation-C03 | Integration and recovery | platform-foundation-R1 | Given a failed migration, the previous database remains recoverable and maintenance mode is visible. | +| platform-foundation-C04 | State and concurrency | platform-foundation-R2 | Given a repeated command key and identical payload, the original result returns and balances do not change. | +| platform-foundation-C05 | State and concurrency | platform-foundation-R2 | Given a repeated key with a different payload, a conflict returns without applying it. | +| platform-foundation-C06 | Adapters and persistence | platform-foundation-R2 | Given a crash between domain SQL and outbox SQL, the transaction leaves neither effect committed. | +| platform-foundation-C07 | Deployment and contracts | platform-foundation-R3 | Given a Supervisor test installation, the packaged application opens under its Ingress prefix and retains data. | +| platform-foundation-C08 | Deployment and contracts | platform-foundation-R3 | Given standalone Compose without Supervisor, the same household workflow completes with Core APIs. | +| platform-foundation-C09 | Integration and recovery | platform-foundation-R3 | Given the same command fixtures, both deployment targets produce equivalent domain results. | +| platform-foundation-C10 | Integration and recovery | platform-foundation-R4 | Given Internet and gateway outages, authenticated users create and complete local tasks. | +| platform-foundation-C11 | UI and accessibility | platform-foundation-R4 | Given HA disconnection, the integration panel says what is unavailable while showing retained household facts. | +| platform-foundation-C12 | Security and privacy | platform-foundation-R4 | Given an expired session during HA outage, new mutations require reauthentication rather than trusting a stale identity. | +| platform-foundation-C13 | Adapters and persistence | platform-foundation-R5 | Given a consistent snapshot during writes, restoration reproduces stock and points ledger totals. | +| platform-foundation-C14 | Integration and recovery | platform-foundation-R5 | Given a corrupt backup, verification rejects it without replacing the active database. | +| platform-foundation-C15 | State and concurrency | platform-foundation-R5 | Given restoration of command receipts, retrying a previously committed command does not duplicate its effects. | +| platform-foundation-C16 | Deployment and contracts | platform-foundation-R6 | Given a domain import of a concrete HTTP client, the dependency-boundary check fails. | +| platform-foundation-C17 | Security and privacy | platform-foundation-R6 | Given an exception containing a credential, logs and diagnostic exports contain only a safe code. | +| platform-foundation-C18 | Deployment and contracts | platform-foundation-R6 | Given an application adapter cycle, the architecture check rejects the candidate. | +| platform-foundation-C19 | Integration and recovery | platform-foundation-R2, platform-foundation-R5 | Given activity-retention cleanup after a completion and reopening, replaying the old command after restart or consistent restore still resolves its retained receipt/guard and cannot create a new completion or material movement. | +| platform-foundation-C20 | Security and privacy | platform-foundation-R2, platform-foundation-R6 | Given an unauthorized principal presenting another member's operation key, result lookup/replay denies access and applies no effect rather than treating the receipt as authentication. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/platform-foundation.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| platform-foundation-R1 | platform-foundation-C01, platform-foundation-C02, platform-foundation-C03 | +| platform-foundation-R2 | platform-foundation-C04, platform-foundation-C05, platform-foundation-C06, platform-foundation-C19, platform-foundation-C20 | +| platform-foundation-R3 | platform-foundation-C07, platform-foundation-C08, platform-foundation-C09 | +| platform-foundation-R4 | platform-foundation-C10, platform-foundation-C11, platform-foundation-C12 | +| platform-foundation-R5 | platform-foundation-C13, platform-foundation-C14, platform-foundation-C15, platform-foundation-C19 | +| platform-foundation-R6 | platform-foundation-C16, platform-foundation-C17, platform-foundation-C18, platform-foundation-C20 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/points-rewards.md b/specs/points-rewards.md new file mode 100644 index 0000000..f5682d3 --- /dev/null +++ b/specs/points-rewards.md @@ -0,0 +1,337 @@ +# Auditable points, participation and optional rewards + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: points-rewards +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Task completion produces auditable point entries. Household-configurable collaboration policies determine each share and the actual award total; corrections preserve history and optional rewards never control basic participation. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed remainder/override review; child-facing review. The owner confirmed configurable allocation, role-default verification, actual-work reporting, factual negative balances and a funding hold on approved/unfulfilled redemptions without sufficient backing after reversal. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Task completion produces auditable point entries. Household-configurable collaboration policies determine each share and the actual award total; corrections preserve history and optional rewards never control basic participation. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +A mutable points integer cannot explain duplicate awards, reopened tasks, policy changes or who earned credit. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Performer; verifier; administrator; participation viewer. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| points-rewards-R1 | Point awards MUST be append-only, attributable and unique for each accepted completion cycle; all performer shares MUST commit atomically and a policy/version change MUST NOT admit a second award set. | +| points-rewards-R2 | Reopening and correction MUST append compensating entries for the amounts actually awarded and preserve the original award, precision and allocation-policy snapshot. | +| points-rewards-R3 | Collaborative awards MUST apply an administrator-configurable household allocation policy, support conserved splits, rounded equal shares, two-decimal shares and full points per participant, and expose the base value, participants, policy, individual shares and actual awarded total. | +| points-rewards-R4 | Verification and permissions MUST apply adult/no-verification and restricted/adult-approval defaults, prevent premature or unauthorized awards and deny unauthorized task-value or allocation-policy manipulation. | +| points-rewards-R5 | Weekly, monthly and historical earned-point/participation summaries MUST attribute work to actual completed_at under household calendar boundaries, expose effort and participation, and distinguish pending points from posted spendable balance; later approval MUST NOT move the work to another period. | +| points-rewards-R6 | Optional rewards MUST support explicit approval, cancellation and duplicate-safe redemption; reversal MUST preserve factual negative balances and fulfilled rewards, block unaffordable new redemptions and hold approved/unfulfilled rewards without sufficient backing until credit recovers or an explicit authorized resolution occurs. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +PointsLedgerEntry has immutable ID, member, signed integer minor-point amount, completion-cycle source, source-event identity, allocation-policy version, precision, reason, issuer and timestamp. One point is 100 minor units so two-decimal awards use exact integer arithmetic rather than binary floating point. One allocation record is unique per household and completion cycle; each performer has at most one share in that allocation. Policy/version is immutable evidence, not part of a uniqueness key that could permit a second award for the same cycle. Reversal entries reference original entries; balances are projections. + +The owner's expanded decision on 2026-10-29 supersedes universal conservation of the task's base point value: families configure allocation in the application. A household policy supplies the default; only an administrator-authorized task override may change it. The completion and award snapshot the base value, policy/version, precision, performers, shares and actual total. A later policy edit affects future completions, not recorded or retrying awards. A member cannot choose a more rewarding policy in an ordinary completion request. Equal division of one conserved total remains the initial default; other supported modes intentionally may award less or more than that base. + +| Mode | Ten base points, three performers | Actual total | Meaning | +|---|---|---:|---| +| conserve_total, precision 0 | 3, 3, 4 | 10 | Preserve one total; explicit deterministic remainder distribution | +| equal_share, precision 0, floor | 3, 3, 3 | 9 | Same rounded-down share for all | +| equal_share, precision 0, ceil | 4, 4, 4 | 12 | Same rounded-up share for all | +| equal_share, precision 2, floor | 3.33, 3.33, 3.33 | 9.99 | Two-decimal equal shares; no hidden extra 0.01 award | +| conserve_total, precision 2 | 3.33, 3.33, 3.34 | 10 | Two-decimal split preserving the total | +| full_per_participant | 10, 10, 10 | 30 | Every performer earns the full task value | +| manual | Explicit authorized amounts, for example 3, 3, 4 | Sum of entered amounts | Validate every share and show the resulting total before approval | + +Only conserve_total enforces equality between base and awarded total. Other modes record the difference as policy semantics, not duplicate awards or an unexplained adjustment. The proposed remainder strategy rotates eligible recipients deterministically using durable allocation order; replay cannot advance it twice. Its exact fairness/tie-break rule remains an engineering review item. Task value and policy changes affect future completions only. Optional rewards define cost, eligibility, redemption and approval; no punitive streak resets. + +Validate precision against the actual policy rather than silently rounding stored facts. For conserve_total at precision 0, a base of 10.50 cannot be represented as integer shares summing exactly to that base: reject the combination and offer precision 2. Full-performer and manual shares must also be representable at the selected precision. equal_share may intentionally change the total through its explicit rounding policy. Individual award shares are nonnegative; negative ledger entries arise from separately authorized reversal/correction or spending, never a disguised negative performer allocation. + +### 6.2 States and alternatives + +Completion -> awaiting verification or eligible -> awarded. Award -> reversed through compensation; corrections are new entries. Redemption requested -> approved -> fulfilled or cancelled; approved -> funding_hold -> approved or explicitly cancelled when backing credit is lost. Hold preserves the original approval and is not fulfillment. Points are reserved transactionally and released on cancellation, with no double spend. + +One transaction commits the complete performer allocation, exact total, durable remainder-order advancement and inbox receipt. A crash cannot expose only some performers' awards. A reopened or rejected completion cycle is durably closed to later awards; if that closing event arrives before its completion/approval event, the late event cannot issue points. Already-posted awards are reversed once; an unawarded cycle produces no fabricated negative reversal. A genuine new completion of a reopened occurrence has its own cycle ID and may earn one new allocation under its own snapshot. + +The owner confirmed that reopening reverses the full actual award even if some points have already been spent. The resulting ledger balance may be negative; never clamp it to zero, reduce the reversal or erase the redemption to hide the deficit. Fulfilled rewards stay fulfilled. New redemption requests/reservations are blocked while the spendable balance is negative and always require sufficient unreserved points for their cost. Later earned points offset the deficit through ordinary ledger arithmetic. The UI explains the cause and linked entries without a punishment or demand to return an already-delivered reward. Reversal and redemption admission serialize against the same member balance so a racing request cannot spend credit already reversed. + +The owner also confirmed a funding hold when reversal removes the backing for an approved reward not yet delivered. Retain its approval, cost snapshot and reservation, expose the shortfall and block delivery while credit is insufficient. Do not silently cancel, release its reservation or mark it fulfilled. Admission reserves the cost; fulfillment atomically posts one spend debit and releases that same reservation, so the cost is not subtracted twice. Fulfillment requires posted balance minus other active reservations to cover its own cost. Check affordability and record fulfillment atomically, serializing with reversal and reservation/funding-state updates. Recovering credit can restore funded approval, but physical delivery still requires its normal authorized fulfillment command. Explicit reviewed cancellation/correction retains actor and reason; cancellation releases its reservation once. Review cannot bypass affordability or fabricate credit. Existing fulfilled rewards are outside this hold and remain delivered. + +The owner confirmed that work performed on Sunday and approved on Monday belongs to Sunday's household week. Retain actual completed_at as the work-period timestamp, verified_at as the approval fact and ledger posted_at as the time credit becomes available. Pending verification may appear as pending participation/points, never as spendable credit. After approval, the historical earned-points summary updates in the work period while the balance gains credit at posting. Linked reversals correct that original work period and retain their real later posting/audit timestamp. Weekly earned points, lifetime ledger balance and spendable balance after reservations are distinct views; a reward debit is spending rather than a new negative task-performance record. Month/week boundaries and all projections use the same household-zone policy, not the viewing browser's zone. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `points_enabled` | boolean | true | false hides summaries but preserves existing ledger | household; persisted | +| `default_task_points` | decimal points | 0 | 0..10000, at most 2 decimals; administrator-controlled | definition; completion snapshot, stored as minor units | +| `collaborative_allocation_mode` | enum | conserve_total | conserve_total, equal_share, full_per_participant or manual; administrator-controlled | household default; authorized task override; completion/award snapshot | +| `allocation_precision` | integer | 0 | 0 or 2 decimal places; exact minor-unit arithmetic | same allocation-policy snapshot | +| `allocation_rounding` | enum | floor | floor, ceil or half_up for equal_share; reject irrelevant/contradictory combinations | same allocation-policy snapshot | +| `allocation_remainder_strategy` | enum | rotating | proposed rotating distribution for conserve_total only; deterministic and replay-safe | durable order plus allocation-policy snapshot | +| `rewards_enabled` | boolean | false | true or false; optional, not a launch dependency | household; persisted | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: conserve_total splits one task value using exact minor units. Meaningful alternative: an authorized household policy selects full_per_participant and the preview discloses the resulting larger actual total before completion. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +AwardCompletionPoints and ReverseCompletionPoints consume durable task events through an inbox receipt and ledger transaction, serializing lifecycle closure and allocation for the same completion cycle. AllocationPolicy is pure. QueryParticipation aggregates ledger, durations and counts without overwriting facts. The ledger adapter is append-only to application roles. Reward redemption uses the same concurrency and receipt controls. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Updating participation totals. Your completed task is saved. | +| Action required | This task needs verification before points can be awarded. View task. | +| Blocked | You cannot change this award. Ask a household administrator; existing points are unchanged. | +| Partial | Completion is saved. Its point award is waiting for processing. View activity. | +| Complete | 12 points awarded to Alex. View the ledger entry. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 44 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| State and concurrency | 10 | the same completion event delivered twice; a reopened task; two redemptions competing for the same available points | +| Adapters and persistence | 4 | a displayed balance; corrected historical entries | +| Security and privacy | 4 | a member attempting to overwrite an existing ledger amount; pending completion verification; an adult without point-administration permission | +| Domain and configuration | 13 | a later task-value edit; 10 points and three performers; duplicate or inactive performer IDs | +| Integration and recovery | 8 | repeated correction commands; authorized approval after a retry; a cancelled pending redemption | +| UI and accessibility | 5 | collaborative completion; equal point totals with different durations; rewards disabled | +| **Total** | **44** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| points-rewards-C01 | State and concurrency | points-rewards-R1 | Given the same completion event delivered twice, only one award set exists. | +| points-rewards-C02 | Adapters and persistence | points-rewards-R1 | Given a displayed balance, drilling into it lists every source award and correction. | +| points-rewards-C03 | Security and privacy | points-rewards-R1 | Given a member attempting to overwrite an existing ledger amount, the operation is denied. | +| points-rewards-C04 | State and concurrency | points-rewards-R2 | Given a reopened task, one reversal offsets its award while retaining both entries. | +| points-rewards-C05 | Domain and configuration | points-rewards-R2 | Given a later task-value edit, the old award keeps the accepted value. | +| points-rewards-C06 | Integration and recovery | points-rewards-R2 | Given repeated correction commands, one compensating entry is applied. | +| points-rewards-C07 | Domain and configuration | points-rewards-R3 | Given conserve_total with precision 0, 10 base points and three performers, shares are 3, 3 and 4, total 10, with the extra recipient determined by the snapshotted remainder strategy. | +| points-rewards-C08 | Domain and configuration | points-rewards-R3 | Given duplicate or inactive performer IDs, allocation is rejected before an award. | +| points-rewards-C09 | UI and accessibility | points-rewards-R3 | Given collaborative completion, members see the base points, allocation mode, each share and actual awarded total before submission. | +| points-rewards-C10 | Security and privacy | points-rewards-R4 | Given pending completion verification, the ledger contains no award. | +| points-rewards-C11 | Security and privacy | points-rewards-R4 | Given an adult without point-administration permission, changing an award policy is denied. | +| points-rewards-C12 | Integration and recovery | points-rewards-R4 | Given authorized approval after a retry, the completion produces one award set. | +| points-rewards-C13 | Domain and configuration | points-rewards-R5 | Given work completed Sunday and approved Monday in the household zone, approved points and participation belong to Sunday's week and become spendable only after Monday's approval/posting. | +| points-rewards-C14 | UI and accessibility | points-rewards-R5 | Given equal point totals with different durations, the report shows both effort and task counts. | +| points-rewards-C15 | Adapters and persistence | points-rewards-R5 | Given corrected historical entries, summary totals reconcile exactly with ledger sums. | +| points-rewards-C16 | State and concurrency | points-rewards-R6 | Given two redemptions competing for the same available points, only the affordable transaction succeeds. | +| points-rewards-C17 | Integration and recovery | points-rewards-R6 | Given a cancelled pending redemption, its reservation is released once. | +| points-rewards-C18 | UI and accessibility | points-rewards-R6 | Given rewards disabled, members can complete tasks normally and no streak penalty is shown. | +| points-rewards-C19 | Domain and configuration | points-rewards-R3 | Given equal_share with precision 0 and floor, 10 base points across three performers awards 3 each and records actual total 9. | +| points-rewards-C20 | Domain and configuration | points-rewards-R3 | Given equal_share with precision 0 and ceil, 10 base points across three performers awards 4 each and records actual total 12. | +| points-rewards-C21 | Domain and configuration | points-rewards-R3 | Given equal_share with precision 2 and floor, 10 base points across three performers awards exactly 3.33 each and records total 9.99 without floating-point drift. | +| points-rewards-C22 | Domain and configuration | points-rewards-R3 | Given full_per_participant, three performers of a 10-point task each receive 10 and the recorded awarded total is 30. | +| points-rewards-C23 | Domain and configuration | points-rewards-R3 | Given authorized manual shares 3, 3 and 4, validation records those exact amounts and total 10; invalid or duplicate performer allocations are rejected. | +| points-rewards-C24 | State and concurrency | points-rewards-R2, points-rewards-R3 | Given a policy change after completion was recorded, a delayed award or retry uses the original snapshotted policy and does not recalculate historical shares. | +| points-rewards-C25 | Security and privacy | points-rewards-R4 | Given a restricted performer supplying full_per_participant in an ordinary completion request, authorization rejects the policy override without increasing their award. | +| points-rewards-C26 | Integration and recovery | points-rewards-R2 | Given a full_per_participant award of 30 actual points from a base of 10, reopening reverses all 30 actual points exactly once. | +| points-rewards-C27 | UI and accessibility | points-rewards-R3 | Given ceil allocation producing 12 actual points from 10 base points, the application explains the selected policy and difference before the award and in its ledger history. | +| points-rewards-C28 | State and concurrency | points-rewards-R1, points-rewards-R3 | Given an already-awarded completion cycle redelivered with a different event or policy version, no second allocation is admitted and the original snapshot remains authoritative. | +| points-rewards-C29 | Adapters and persistence | points-rewards-R1, points-rewards-R3 | Given failure while writing the second of three performer shares, allocation, balance effects, remainder order and inbox receipt all roll back; recovery commits one complete allocation. | +| points-rewards-C30 | Integration and recovery | points-rewards-R1, points-rewards-R2, points-rewards-R4 | Given cycle reopening delivered before its delayed completion or approval, the closed-cycle record prevents an award and no negative reversal is fabricated for an unawarded cycle. | +| points-rewards-C31 | State and concurrency | points-rewards-R1, points-rewards-R2 | Given an awarded cycle reopened and the occurrence genuinely completed again, the old award has one linked reversal and the new cycle has at most one independent allocation; late old messages change neither. | +| points-rewards-C32 | Integration and recovery | points-rewards-R2, points-rewards-R6 | Given 10 awarded points, an 8-point fulfilled reward and reopening, one full 10-point reversal leaves balance -8, retains the fulfilled reward and blocks new redemption. | +| points-rewards-C33 | UI and accessibility | points-rewards-R5, points-rewards-R6 | Given a negative balance caused by reopening, history explains the award, redemption and reversal with the exact deficit and recovery path, without requesting return of the delivered reward. | +| points-rewards-C34 | State and concurrency | points-rewards-R2, points-rewards-R6 | Given a reversal racing a new redemption request, serialization enforces affordability against committed balance and never admits a request based on already-reversed points. | +| points-rewards-C35 | Domain and configuration | points-rewards-R6 | Given balance -8 followed by ordinary earnings of 5 then 4, balances become -3 then 1; new redemptions remain blocked during the deficit and only an affordable cost can be requested afterward. | +| points-rewards-C36 | State and concurrency | points-rewards-R4, points-rewards-R5 | Given approval delayed past month-end, pending points are not spendable before approval and the eventual single posting updates the original work-month summary without moving the task or duplicating credit. | +| points-rewards-C37 | Integration and recovery | points-rewards-R2, points-rewards-R5 | Given reversal several weeks after an award, the original work-period earned total is corrected once while activity and ledger preserve the reversal's real posting timestamp and current balance effect. | +| points-rewards-C38 | Adapters and persistence | points-rewards-R5, points-rewards-R6 | Given prior-period earnings and a reward debit this week, the weekly work total, lifetime balance and available balance after reservations remain distinct and reconcile to their appropriate source entries. | +| points-rewards-C39 | Domain and configuration | points-rewards-R3 | Given conserve_total, precision 0 and base 10.50, validation rejects the incompatible combination with a precision-2 option instead of silently rounding the base or violating conservation. | +| points-rewards-C40 | Domain and configuration | points-rewards-R3, points-rewards-R4 | Given manual allocation with a negative share or a share not representable at its selected precision, validation rejects it before any award or remainder-state change. | +| points-rewards-C41 | Integration and recovery | points-rewards-R2, points-rewards-R6 | Given an approved unfulfilled reward whose backing points are reversed, the full reversal commits and the reward enters funding_hold with its approval and reservation retained; delivery is blocked and no spend debit is fabricated. | +| points-rewards-C42 | State and concurrency | points-rewards-R2, points-rewards-R6 | Given reversal racing fulfillment, serialization either records a genuinely funded fulfillment before reversal or blocks the unfunded delivery; it never fulfills using already-reversed credit. | +| points-rewards-C43 | Domain and configuration | points-rewards-R6 | Given a held reward and later earnings sufficient to cover its cost and other reservations, funded approval may resume but no automatic delivery occurs; authorized fulfillment posts one debit and releases its own reservation once. | +| points-rewards-C44 | State and concurrency | points-rewards-R1, points-rewards-R6 | Given explicit cancellation of a held redemption followed by replay or restart, one retained cancellation releases its reservation once without deleting approval, reversing delivered rewards or generating credit. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/points-rewards.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| points-rewards-R1 | points-rewards-C01, points-rewards-C02, points-rewards-C03, points-rewards-C28, points-rewards-C29, points-rewards-C30, points-rewards-C31, points-rewards-C44 | +| points-rewards-R2 | points-rewards-C04, points-rewards-C05, points-rewards-C06, points-rewards-C24, points-rewards-C26, points-rewards-C30, points-rewards-C31, points-rewards-C32, points-rewards-C34, points-rewards-C37, points-rewards-C41, points-rewards-C42 | +| points-rewards-R3 | points-rewards-C07, points-rewards-C08, points-rewards-C09, points-rewards-C19, points-rewards-C20, points-rewards-C21, points-rewards-C22, points-rewards-C23, points-rewards-C24, points-rewards-C27, points-rewards-C28, points-rewards-C29, points-rewards-C39, points-rewards-C40 | +| points-rewards-R4 | points-rewards-C10, points-rewards-C11, points-rewards-C12, points-rewards-C25, points-rewards-C30, points-rewards-C36, points-rewards-C40 | +| points-rewards-R5 | points-rewards-C13, points-rewards-C14, points-rewards-C15, points-rewards-C33, points-rewards-C36, points-rewards-C37, points-rewards-C38 | +| points-rewards-R6 | points-rewards-C16, points-rewards-C17, points-rewards-C18, points-rewards-C32, points-rewards-C33, points-rewards-C34, points-rewards-C35, points-rewards-C38, points-rewards-C41, points-rewards-C42, points-rewards-C43, points-rewards-C44 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/recurrence-calendar.md b/specs/recurrence-calendar.md new file mode 100644 index 0000000..45a6632 --- /dev/null +++ b/specs/recurrence-calendar.md @@ -0,0 +1,320 @@ +# Recurrence engine and family calendar + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: recurrence-calendar +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: A bounded scheduler turns task definitions into stable occurrences and a family calendar distinguishes planned start, deadline and actual completion. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Supported RRULE subset, time-zone/gap/fold library interoperability and calendar projection review. The owner confirmed first-instant execution for repeated local times with a household-configurable second-instant option, alongside gap advancement, actual-completion anchoring, successor/missed-work defaults and previewed future rule edits. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +A bounded scheduler turns task definitions into stable occurrences and a family calendar distinguishes planned start, deadline and actual completion. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +Recurring household work must handle late completion, time zones, exceptions and restarts without drifting fixed schedules or generating unlimited work. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Household planner; assigned member; scheduler; calendar reader. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| recurrence-calendar-R1 | Fixed recurrence MUST preserve its local calendar anchor after late completion, with a documented supported RFC 5545 subset. | +| recurrence-calendar-R2 | Completion-relative recurrence MUST calculate one successor from actual completed_at, never shift its anchor to verified_at, default to showing it when work is recorded, support an authorized per-task at_verification alternative and handle reopening without orphaned silent work. | +| recurrence-calendar-R3 | Materialization MUST be bounded by time horizon and per-run count and remain duplicate-free across concurrent runs and restarts. | +| recurrence-calendar-R4 | Time handling MUST preserve IANA zones and date-only deadlines; a nonexistent scheduled wall time advances once to the first valid local instant at or after it; a repeated wall time MUST execute once in the first appearance by default with a household-configurable second-appearance option, retaining nominal identity and exposing the resolution. | +| recurrence-calendar-R5 | Pausing, skipping, rescheduling and editing rules MUST preserve exceptions and history; rule edits MUST preview changes and update only future unstarted occurrences, retaining started work; missed-occurrence handling MUST be configurable per task, retain all visibly pending by default and support explicit skip without completion points. | +| recurrence-calendar-R6 | The calendar MUST distinguish planned start, deadline and actual completion and support month, week, day and agenda views. | +| recurrence-calendar-R7 | Calendar queries MUST support bounded ranges and member, category, status, priority and task-type filters without exposing unauthorized records. | +| recurrence-calendar-R8 | HA calendar export MUST use stable identifiers and mark unavailable projections honestly; external calendar sync remains optional and disabled initially. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +RecurrenceRule is fixed-calendar or completion-relative, never both. Fixed rules store local DTSTART, IANA zone, supported RFC 5545 rule, exceptions and rule revision; occurrence identity includes definition, nominal local occurrence and rule revision. Relative schedules store interval in local calendar days and the accepted completion's actual completed_at separately from any verified_at timestamp. Calendar entries distinguish scheduled work, due-only markers, completion history and household events. Each occurrence retains its original planned time when rescheduled. + +The owner confirmed that verification delay does not postpone the next relative task. For a 30-day interval, work performed on January 1 and approved on January 5 anchors the successor to January 31, not February 4. Successor timing is configurable per task: at_completion is the default and creates/shows the next occurrence when work is recorded, even if its points are waiting for approval; at_verification waits for approval but retains the date derived from completed_at. If approval arrives after that date, the successor is shown as due/overdue rather than shifted into a new future interval or silently omitted. Rejection/reopening invalidates an unstarted derived successor; active downstream work is retained with a visible review conflict instead of being deleted. + +The owner confirmed on 2026-10-29 that a task must not disappear because its local clock time is in a daylight-saving gap. Domus preserves the intended local slot, then resolves the execution instant forward to the first valid local time at or after that slot. For a gap from 02:00 to 03:00, an intended 02:30 occurrence resolves to 03:00. This is a Domus scheduling policy layered explicitly over nominal recurrence generation, not a claim that raw RFC 5545 expansion uses this policy. Export includes the resolved instant and stable nominal identity; an importer must not silently reinterpret the adjustment. A date with no valid local instant at all is not assumed handled by this gap rule and remains a boundary decision for supported-zone review. + +The owner also confirmed repeated autumn wall times: generate one nominal occurrence, resolve it to the first appearance by default, and allow the household to choose the second appearance. Never generate both merely because two UTC instants share that wall time. Snapshot the household time policy with the rule/occurrence and show the selected appearance and resolved offset in preview/history. A later policy edit follows the existing preview/revision rules for unstarted future work; it cannot duplicate an active/completed occurrence or rewrite its recorded instant. + +The owner confirmed that editing recurrence first previews the affected generated occurrences and then updates only future work that has not started. The preview names retained, moved, replaced and added slots; started, completed, skipped or cancelled history is preserved. Explicit one-off exceptions and manual reschedules are retained by default and conflicts are disclosed. An affected unstarted slot that disappears is cancelled with a recurrence-replacement reason and linked replacement when one exists, not deleted. Preserve compatible assignments and annotations, and expose anything requiring review rather than dropping it. Replacement slots have the new nominal/rule identity; the old record stays traceable. Reservation/demand adjustments use their owning domain commands and do not delete manual shopping extras or change physical stock. + +Applying a preview checks the rule and affected occurrence revisions. If someone started an occurrence meanwhile, reject the stale plan and recalculate; never overwrite that work. A bounded accepted plan commits its rule/occurrence changes and outbox references together and returns one receipt on replay. If the selected plan exceeds the reviewed bound or overlaps retained active work, require an explicit conflict resolution or narrower plan before applying it rather than silently truncating or duplicating the work. + +### 6.2 States and alternatives + +Rule active <-> paused -> retired. Pause stops new materialization, preserving existing occurrences; resume previews missed dates. Occurrence skip/cancel/reschedule is an exception and never silently rewrites history. Fixed schedules completed late keep future anchored dates. The owner confirmed configurable missed-work handling per task with keep_visible as the default: four missed weekly slots remain four identifiable pending occurrences, rather than becoming completed or disappearing. Explicit skip preserves each occurrence's nominal identity, actor, reason and skipped state, awards no completion points and never changes the next fixed anchor. Alternative missed-work policies require explicit configuration and clear preview; retrying a skip or resume cannot erase history or duplicate occurrences. Relative schedules calculate one successor from the actual completed_at date of accepted work, independently of a later approval timestamp; reopening invalidates an unstarted successor and requires review if that successor is already in progress. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `materialization_horizon_days` | integer | 60 | 7..366; at most 1000 generated occurrences per definition per run | household; scheduler snapshots | +| `missed_occurrence_policy` | enum | keep_visible, owner-confirmed | keep_visible or explicitly skip_after_review; never mark missed work as completed | per-task definition; versioned | +| `ambiguous_local_time` | enum | first_instant, owner-confirmed | first_instant or second_instant; exactly one appearance executes | household; rule/occurrence snapshots; future changes require preview | +| `nonexistent_local_time` | enum | next_valid_instant | next_valid_instant; first valid local time at or after the intended time, retaining the nominal slot | household; rule snapshots | +| `calendar_week_start` | enum | monday | monday or sunday | member preference | +| `relative_successor_timing` | enum | at_completion | at_completion or at_verification; authorized per-task setting | definition version; completion snapshots the effective setting | + +Owner-confirmed defaults are recorded as accepted choices; other defaults and bounds remain proposals pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: keep missed work visible and release relative successors at completion. Meaningful alternative: an authorized task setting waits for verification while retaining the same completed_at-based successor date. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +RecurrencePolicy and CalendarProjection are pure. MaterializeOccurrences uses a clock, bounded recurrence library adapter, occurrence uniqueness constraints and a persisted scheduler cursor. Rebuilds never change completed occurrences. A range query projects scheduled events and actual history separately. HA calendar adapters read this projection rather than treating last completion as the next event. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Loading this week's household plan. | +| Action required | This recurrence uses a daylight-saving transition. Review the preview before saving. | +| Blocked | This recurrence is not supported. Your draft is retained. Choose a supported schedule. | +| Partial | The task was rescheduled. The HA calendar will refresh after reconnection. | +| Complete | Saturday's task is complete. The next fixed occurrence is next Saturday. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 37 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| Domain and configuration | 10 | a Saturday rule completed on Monday; a monthly day-31 rule; an unsupported RRULE part | +| State and concurrency | 9 | a relative 30-day rule completed late; reopening before the successor starts; parallel scheduler runs | +| Integration and recovery | 7 | reopening after the successor starts; a crash after a batch commit; combined category and status filters | +| Adapters and persistence | 4 | a date-only deadline; an edited rule; HA calendar reads after a retry | +| UI and accessibility | 4 | a task scheduled yesterday and completed today; narrow-screen month view; a due-only task | +| Security and privacy | 2 | a member filter; no external calendar setup | +| Deployment and contracts | 1 | an excessive range | +| **Total** | **37** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| recurrence-calendar-C01 | Domain and configuration | recurrence-calendar-R1 | Given a Saturday rule completed on Monday, the next fixed occurrence remains on Saturday. | +| recurrence-calendar-C02 | Domain and configuration | recurrence-calendar-R1 | Given a monthly day-31 rule, months without that date follow the documented RFC-compatible omission policy. | +| recurrence-calendar-C03 | Domain and configuration | recurrence-calendar-R1 | Given an unsupported RRULE part, setup rejects it rather than partially interpreting the rule. | +| recurrence-calendar-C04 | State and concurrency | recurrence-calendar-R2 | Given a relative 30-day rule performed late, its next due date is 30 local calendar days after actual completed_at, independent of the approval timestamp. | +| recurrence-calendar-C05 | State and concurrency | recurrence-calendar-R2 | Given reopening before the successor starts, that successor is invalidated and linked history remains. | +| recurrence-calendar-C06 | Integration and recovery | recurrence-calendar-R2 | Given reopening after the successor starts, the calendar flags a review conflict instead of deleting active work. | +| recurrence-calendar-C07 | State and concurrency | recurrence-calendar-R3 | Given parallel scheduler runs, uniqueness constraints produce one occurrence per nominal slot. | +| recurrence-calendar-C08 | Integration and recovery | recurrence-calendar-R3 | Given a crash after a batch commit, restart resumes without duplicating prior occurrences. | +| recurrence-calendar-C09 | Domain and configuration | recurrence-calendar-R3 | Given an unbounded daily rule, a run stops at the horizon or 1000 occurrences and retains a continuation cursor. | +| recurrence-calendar-C10 | Domain and configuration | recurrence-calendar-R4 | Given a 02:30 task inside a 02:00–03:00 clock gap, scheduling resolves it once to 03:00, preserves its nominal occurrence key and displays the adjustment rather than dropping the task. | +| recurrence-calendar-C11 | Domain and configuration | recurrence-calendar-R4 | Given an autumn repeated hour, only the configured instant is generated with its offset. | +| recurrence-calendar-C12 | Adapters and persistence | recurrence-calendar-R4 | Given a date-only deadline, switching display zones does not shift it into another date. | +| recurrence-calendar-C13 | State and concurrency | recurrence-calendar-R5 | Given a paused definition, no new occurrences appear while existing assigned work remains visible. | +| recurrence-calendar-C14 | Adapters and persistence | recurrence-calendar-R5 | Given an edited rule, completed past occurrences retain their original dates and rule revision. | +| recurrence-calendar-C15 | State and concurrency | recurrence-calendar-R5 | Given a skipped or rescheduled exception, rebuilding the same range preserves that exception. | +| recurrence-calendar-C16 | UI and accessibility | recurrence-calendar-R6 | Given a task scheduled yesterday and completed today, scheduled and history views label both times distinctly. | +| recurrence-calendar-C17 | UI and accessibility | recurrence-calendar-R6 | Given narrow-screen month view, the user can switch to a readable agenda with keyboard controls. | +| recurrence-calendar-C18 | UI and accessibility | recurrence-calendar-R6 | Given a due-only task, the calendar uses a due marker without inventing a scheduled duration. | +| recurrence-calendar-C19 | Security and privacy | recurrence-calendar-R7 | Given a member filter, only records the principal may view are returned. | +| recurrence-calendar-C20 | Deployment and contracts | recurrence-calendar-R7 | Given an excessive range, the API rejects it with its supported limit and keeps existing selections. | +| recurrence-calendar-C21 | Integration and recovery | recurrence-calendar-R7 | Given combined category and status filters, counts and agenda entries use the same predicate. | +| recurrence-calendar-C22 | Adapters and persistence | recurrence-calendar-R8 | Given HA calendar reads after a retry, stable event UIDs remain unchanged. | +| recurrence-calendar-C23 | Integration and recovery | recurrence-calendar-R8 | Given backend unavailability, HA calendar becomes unavailable rather than reporting an empty household. | +| recurrence-calendar-C24 | Security and privacy | recurrence-calendar-R8 | Given no external calendar setup, no household calendar data leaves the local installation. | +| recurrence-calendar-C25 | Domain and configuration | recurrence-calendar-R2 | Given work performed on January 1 with a 30-day interval and approved January 5, the successor is due January 31 rather than February 4. | +| recurrence-calendar-C26 | Integration and recovery | recurrence-calendar-R2 | Given at_verification and approval after the successor date derived from completed_at, materialization preserves that date, exposes the due/overdue occurrence and creates it only once. | +| recurrence-calendar-C27 | State and concurrency | recurrence-calendar-R2 | Given default at_completion for a restricted performer, recording completed work shows one successor immediately while the original completion's points remain unawarded pending adult approval. | +| recurrence-calendar-C28 | State and concurrency | recurrence-calendar-R2 | Given an authorized per-task at_verification setting, no successor is visible before approval; approval creates it once with the completed_at-based date and snapshotted timing policy. | +| recurrence-calendar-C29 | Domain and configuration | recurrence-calendar-R1, recurrence-calendar-R5 | Given a weekly fixed rule and four missed occurrences under default keep_visible, all four remain individually pending while future slots keep the original calendar anchor; none gains completion points. | +| recurrence-calendar-C30 | Integration and recovery | recurrence-calendar-R3, recurrence-calendar-R5 | Given explicit reviewed skipping of missed occurrences followed by retry or scheduler restart, each retains one skipped exception and its source identity, without duplicate occurrences or awards. | +| recurrence-calendar-C31 | UI and accessibility | recurrence-calendar-R5 | Given a recurrence edit with future unstarted, active and completed occurrences, preview shows affected and retained slots; applying changes only unstarted future work and preserves active/completed records and history. | +| recurrence-calendar-C32 | State and concurrency | recurrence-calendar-R3, recurrence-calendar-R5 | Given an occurrence started after preview, applying that stale preview returns conflict and requires a refreshed plan without overwriting the newly started work. | +| recurrence-calendar-C33 | Integration and recovery | recurrence-calendar-R3, recurrence-calendar-R5 | Given an approved replacement plan whose response is lost, retry returns the same rule revision and linked cancelled/replacement records without duplicate slots or reservation/demand effects. | +| recurrence-calendar-C34 | Domain and configuration | recurrence-calendar-R1, recurrence-calendar-R5 | Given an explicit future exception or a new slot overlapping retained active work, the preview preserves the exception and surfaces the overlap for resolution rather than silently moving or duplicating work. | +| recurrence-calendar-C35 | Domain and configuration | recurrence-calendar-R3, recurrence-calendar-R4 | Given a repeated local wall time and default first_instant, one nominal occurrence resolves to its first appearance and neither scheduler replay nor the second appearance creates another occurrence. | +| recurrence-calendar-C36 | Adapters and persistence | recurrence-calendar-R4, recurrence-calendar-R8 | Given household second_instant, one occurrence resolves to the later appearance with the selected offset/policy retained through persistence, calendar projection and export. | +| recurrence-calendar-C37 | State and concurrency | recurrence-calendar-R3, recurrence-calendar-R4, recurrence-calendar-R5 | Given a fold-policy change after materialization, preview can update only eligible unstarted future work and preserves active/completed occurrence identity and recorded instant without a duplicate execution. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/recurrence-calendar.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| recurrence-calendar-R1 | recurrence-calendar-C01, recurrence-calendar-C02, recurrence-calendar-C03, recurrence-calendar-C29, recurrence-calendar-C34 | +| recurrence-calendar-R2 | recurrence-calendar-C04, recurrence-calendar-C05, recurrence-calendar-C06, recurrence-calendar-C25, recurrence-calendar-C26, recurrence-calendar-C27, recurrence-calendar-C28 | +| recurrence-calendar-R3 | recurrence-calendar-C07, recurrence-calendar-C08, recurrence-calendar-C09, recurrence-calendar-C30, recurrence-calendar-C32, recurrence-calendar-C33, recurrence-calendar-C35, recurrence-calendar-C37 | +| recurrence-calendar-R4 | recurrence-calendar-C10, recurrence-calendar-C11, recurrence-calendar-C12, recurrence-calendar-C35, recurrence-calendar-C36, recurrence-calendar-C37 | +| recurrence-calendar-R5 | recurrence-calendar-C13, recurrence-calendar-C14, recurrence-calendar-C15, recurrence-calendar-C29, recurrence-calendar-C30, recurrence-calendar-C31, recurrence-calendar-C32, recurrence-calendar-C33, recurrence-calendar-C34, recurrence-calendar-C37 | +| recurrence-calendar-R6 | recurrence-calendar-C16, recurrence-calendar-C17, recurrence-calendar-C18 | +| recurrence-calendar-R7 | recurrence-calendar-C19, recurrence-calendar-C20, recurrence-calendar-C21 | +| recurrence-calendar-R8 | recurrence-calendar-C22, recurrence-calendar-C23, recurrence-calendar-C24, recurrence-calendar-C36 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope. diff --git a/specs/shopping-management.md b/specs/shopping-management.md new file mode 100644 index 0000000..1e1ac81 --- /dev/null +++ b/specs/shopping-management.md @@ -0,0 +1,291 @@ +# Shared shopping demand, purchases and receipt + +- Status: Draft +- Date: 2026-10-28 +- Catalog capability ID: shopping-management +- Last verified: 2026-10-29 (document structure only; no implementation evidence) +- Owners: Domus maintainer; engineering/product reviewers to be assigned +- Scope: Shopping combines manual intent, replenishment and task materials without losing provenance. Buying an item and physically receiving it are separate recorded facts. +- Related issues/PRs: https://github.com/vypdev/domus/issues/2 +- Required review gates: product UX, architecture, testing, documentation, security/operations +- Open decisions blocking readiness: Detailed demand-coverage and unit fixtures; partial-receipt UX; price/currency precision; launch purchase-session scope. The owner confirmed manual-extra and duplicate-safe automatic consolidation defaults on 2026-10-29. Catalog gate prerequisites remain unverified. + +## 1. Executive summary + +Shopping combines manual intent, replenishment and task materials without losing provenance. Buying an item and physically receiving it are separate recorded facts. + +```text +Authenticated member -> validated domain command -> durable result -> household and HA projections +``` + +This is a prospective Draft, not an implemented or accepted capability. The first usable release covers all domains and both deployment targets. + +## 2. Problem, current behavior, and evidence + +Checking a shopping box cannot safely represent outstanding demand, partial purchases, shared shoppers and stock receipt. + +Current verified sequence: (1) the repository has a minimal README and installed Copilot automation; (2) no Domus application, public service or tests exist; (3) this contract proposes the behavior to build. + +Evidence: the owner's attached brief and subsequent decisions in [product vision](../docs/product-vision.md), the pinned [reference investigation](../docs/reference-investigation.md), and the existing repository baseline. Retrospective classification is not applicable: no as-built product baseline is reconstructed. + +## 3. Actors, surfaces, and terminology + +Actors: Requester; shopper; receiver; stock administrator. + +Primary surfaces: application UI, HTTP domain boundary, relevant HA entities/services, activity and diagnostics. Definitions of member, principal, occurrence, demand and ledger are shared in the [glossary](../docs/glossary.md). The actor recording an action is distinct from its selected target and actual performer. + +## 4. Goals, non-goals, and fixed invariants + +Goals and fixed invariants are the following normative requirements. No configuration may weaken authorization, ledger integrity, attribution or idempotency. + +| Requirement | Behavior | +|---|---| +| shopping-management-R1 | Shopping MUST accept shared multiple lists and free-text products with quantity, unit, notes, priority and optional shopper/store/prices. | +| shopping-management-R2 | Every demand MUST retain its origin, additive or overlapping semantics and any user-requested extra quantity. | +| shopping-management-R3 | Consolidation MUST reject incompatible units and prevent double-counting reservations or silently discarding manual requests. | +| shopping-management-R4 | Purchase, receipt and inventory posting MUST remain distinct states supporting partial quantities and nontracked goods. | +| shopping-management-R5 | Concurrent shoppers and retries MUST not duplicate purchases, receipts or stock movements. | +| shopping-management-R6 | Purchase history and optional sessions MUST retain shopper, dates, quantities and optional store/prices without requiring a receipt image. | +| shopping-management-R7 | Shopping commands and recovery MUST enforce household permissions, show retained partial facts and preserve cancellable outstanding demand. | + +Non-goals: changing Copilot, changing the existing gateway, building an MCP server, adding mandatory cloud/AI dependencies, or claiming production readiness from a document. + +## 5. Current versus proposed product journey + +| Stage | Current | Proposed | User/operator effect | +|---|---|---|---| +| Enter | No Domus UI | Verified HA principal opens the relevant surface | Role and scope are explicit | +| Act | No domain command | Validate input, permission and current revision | Invalid data leaves the draft intact | +| Commit | No durable domain record | Store change and operation receipt atomically | Retry cannot duplicate effects | +| Observe | No projection | Show committed facts and pending downstream projections | Partial success remains understandable | + +```mermaid +flowchart LR + Entry[Authenticated entry] --> Validate[Authorize and validate] + Validate --> Commit[Commit domain result] + Commit --> View[Show facts and pending work] +``` + +Text equivalent: authenticated entry -> authorization and validation -> durable domain commit -> visible facts with any pending projection. Domain-specific alternatives are described below. + +## 6. Functional behavior and state model + +### 6.1 Domain model and normal path + +ShoppingList, Demand(source_type, source_id, product_or_free_text, amount, unit, semantics, revision), PlannedLine, PurchaseSession, PurchaseItem and Receipt. Free-text items need no product record. Demands remain individually attributable when a line is consolidated. Inventory target demand covers target minus available minus outstanding compatible supply; a task reservation is already reflected in availability and is not added twice. Manual demand is additional by default and can explicitly be marked overlapping. Quantities combine only with identical product, compatible units and declared semantics; ambiguous cases remain separate. + +The owner confirmed on 2026-10-29 that manual requests are additional by default and automatic stock/material demands consolidate without counting the same requirement twice. Consolidation retains each source and its coverage semantics; matching names alone do not establish overlap. If an automatic four-unit demand already covers a reserved task material, that same material is not added again; a manual extra of two still raises the purchase requirement to six. Distinct independent material needs remain additive. This rule does not silently relabel a manual extra as an automatic threshold. + +### 6.2 States and alternatives + +Demand open -> planned -> satisfied or cancelled. Purchase planned -> purchased -> partially_received -> received. Stock posting is a separate durable step tied to each receipt line; a received tracked product is pending stock until posting succeeds. Nontracked items finish at receipt without inventory records. + +A duplicate uses its original operation receipt. A changed payload under the same key is a conflict. Out-of-order events use aggregate revision and source identity. Cancellation never erases an already committed ledger effect; compensation is explicit. + +## 7. User-facing configuration + +| Input | Type | Recommended default | Allowed values/range | Scope/persistence | +|---|---|---|---|---| +| `manual_demand_semantics` | enum | additional | additional or explicitly overlapping | demand; persisted | +| `purchase_currency` | ISO currency | selected at setup | one household currency initially; decimal minor-unit validation | purchase session; snapshot | +| `default_list` | list reference | Household shopping | active list only | household; persisted | +| `auto_receive_purchase` | boolean | false | true allowed only with explicit combined-action UI confirmation | household; command snapshot | + +These are proposed defaults pending review. Invalid values and contradictory combinations are rejected before saving; unknown future values require an explicit compatibility error. Precedence is fixed invariants, installation constraints, household policy, then member preferences; lower scopes cannot expand permissions. In-flight commands snapshot relevant policy versions, while revocation is checked at the transaction boundary. + +Recommended example: keep the defaults above. Meaningful alternative: a member selects Spanish and dark theme while the same household policies remain in force. Transport secrets are installation concerns and are never domain form fields. + +## 8. Clean Architecture design + +### 8.1 Responsibilities and dependency direction + +CreateDemand, ConsolidateDemand, RecordPurchase, ReceivePurchase and PostReceiptStock use separate semantic contracts. A receipt ID and line ID are inventory idempotency sources. The application owns source demand arithmetic; the UI never consolidates by name. Inventory changes and purchase status use transaction/outbox coordination with visible pending state. + +| Boundary | Owns | Forbidden dependency | +|---|---|---| +| Domain | Entities, value objects and pure rules | HA, HTTP, SQL, UI frameworks | +| Application | Authorized commands, queries and semantic ports | Concrete adapters and framework DTOs | +| Adapters | Schema mapping, persistence and provider error mapping | Alternate business rules | +| Composition | Explicit deployment wiring | Business decisions | +| Presentation | View models and rendering | Database access or client-only authorization | + +```mermaid +flowchart LR + UI[UI or HA entry] --> UC[Application use case] + UC --> Domain[Pure domain] + UC --> Port[Semantic port] + Adapter[Infrastructure adapter] --> Port +``` + +Text equivalent: entrypoints call use cases; use cases depend on pure domain and ports; infrastructure implements ports. Architecture checks reject forbidden imports and cycles. Shared contract tests exercise each port adapter; schemas and migration checks enforce durable boundaries. + +## 9. UI/UX and content contract + +### 9.1 Primary state examples + +| State | Visible content | +|---|---| +| Pending | Saving the purchase. No action required. | +| Action required | Four cartons were received. Two are still pending. Record the remaining receipt when it arrives. | +| Blocked | This line changed while another shopper was editing it. Your quantities are retained. Review the latest line. | +| Partial | Purchase and receipt are saved. Inventory posting is pending. Retry stock posting. | +| Complete | Six cartons received and added to inventory. View purchase. | + +The primary view names current status, retained facts and one next action, followed by descriptive links to the record/operation. Technical codes and correlation IDs are progressively disclosed. Duplicate responses update the same operation status rather than adding notifications. At most one routine notification per transition, with opt-out and bounded retry summaries. + +English and Spanish use stable translation keys, base-language matching and English fallback. Mobile, tablet and desktop layouts, keyboard operation, visible focus, non-color status, accessible names, light/dark contrast and reduced motion are acceptance concerns. Untrusted text is rendered inert; no arbitrary HTML, commands or secret-bearing links. + +## 10. Failure, recovery, and cleanup + +| Failure | Retained facts | Retry / action | Cleanup | +|---|---|---|---| +| Invalid or denied input | Existing business records and form draft | Correct fields or request the proper role | No side effects | +| Stale revision | Current committed aggregate; user's entered fields | Review current state and submit a new deliberate operation | No automatic overwrite | +| Lost response after commit | Domain result and receipt | Look up or replay the same key | Never issue a fresh-key duplicate | +| Downstream projection unavailable | Successful domain result and durable pending event | Bounded backoff, then visible retry | Acknowledge outbox only after safe consumption | +| Restart or cancellation | Committed records; identified pending work | Recover receipts/cursors; compensate only by explicit command | Remove listeners and owned temporary artifacts | + +Errors explain impact, safe cause, action and retained state. External availability is distinct from authorization denial. Retries are bounded and use deterministic backoff tests, not real waits. + +## 11. Security, permissions, and privacy + +Backend authorization applies to reads and writes. All requests and HA values are untrusted input; only authenticated principals and validated adapter context establish identity. Cross-household IDs, replayed operations and stale roles are covered in the inventory. A person entity and selected member ID do not authenticate a caller. Logs, traces, exports and browser artifacts redact credentials and unnecessary personal data. The technical HA principal has explicit narrow grants and cannot impersonate a household administrator. + +## 12. Observability and operational UX + +Show operation state and projection freshness to members; expose sanitized correlation, source event, aggregate revision, duration and safe error code to operators. No raw credentials or unrestricted HA payloads enter diagnostics. Counters distinguish denied, invalid, conflict, unavailable and completed operations. One durable activity entry per business transition; retries do not multiply notifications. No telemetry leaves the installation by default. + +## 13. Compatibility, migration, rollout, and rollback + +No existing Domus application data requires migration yet. The first schema is versioned from its first implementation. Upgrade fixtures cover pending operations and ledger compatibility; a backup precedes destructive migration. Unknown future schemas block writes. Downgrade requires a compatible image/database pair, never silent interpretation of newer data. + +Both Supervisor and standalone are first-release acceptance targets. Stable and Edge use separate credentials, IDs, volumes and endpoint bindings. Experimental artifacts cannot automatically promote production. Publication, merge and deployment remain in the existing authorized maintainer lifecycle. + +## 14. Testing strategy and numeric budget + +Minimum: 21 distinct cases, derived from the explicit risk inventory below. Each inventory row counts once. The budget is a floor, not a claim of completeness or executed tests. + +| Area | Minimum distinct cases | Behaviors/risks covered | +|---|---:|---| +| UI and accessibility | 4 | a free-text fruit item; a consolidated line; a session detail view | +| Domain and configuration | 7 | multiple lists; an invalid negative quantity or malformed currency amount; a manual extra of two units | +| Adapters and persistence | 2 | a low-stock demand and manual extra; a purchase session without prices or image | +| State and concurrency | 3 | six units purchased and four received; two shoppers buying the same remaining quantity; a repeated receipt key | +| Integration and recovery | 4 | a nontracked item received; stock posting failure after receipt; a lost purchase response | +| Security and privacy | 1 | a read-only member attempting receipt | +| **Total** | **21** | No double counting | + +| Case ID | Area | Requirements | Scenario | +|---|---|---|---| +| shopping-management-C01 | UI and accessibility | shopping-management-R1 | Given a free-text fruit item, a member adds two kilograms without creating an inventory product. | +| shopping-management-C02 | Domain and configuration | shopping-management-R1 | Given multiple lists, assigning a shopper preserves list ownership and quantities. | +| shopping-management-C03 | Domain and configuration | shopping-management-R1 | Given an invalid negative quantity or malformed currency amount, validation identifies the field. | +| shopping-management-C04 | Adapters and persistence | shopping-management-R2 | Given a low-stock demand and manual extra, both source records remain after consolidation. | +| shopping-management-C05 | Domain and configuration | shopping-management-R2 | Given a manual extra of two units, replenishment does not silently absorb those two units. | +| shopping-management-C06 | UI and accessibility | shopping-management-R2 | Given a consolidated line, expanding it shows each source and its semantics. | +| shopping-management-C07 | Domain and configuration | shopping-management-R3 | Given target 10 and available 6 after a task reservation, replenishment requests four rather than adding the reservation twice. | +| shopping-management-C08 | Domain and configuration | shopping-management-R3 | Given incompatible piece and kilogram demands, the list keeps separate lines. | +| shopping-management-C09 | Domain and configuration | shopping-management-R3 | Given compatible overlapping baseline demands, consolidation uses their declared coverage rather than blindly summing them. | +| shopping-management-C10 | State and concurrency | shopping-management-R4 | Given six units purchased and four received, two remain pending receipt and only four can enter stock. | +| shopping-management-C11 | Integration and recovery | shopping-management-R4 | Given a nontracked item received, it completes without a stock movement. | +| shopping-management-C12 | Integration and recovery | shopping-management-R4 | Given stock posting failure after receipt, receipt stays saved and posting is explicitly pending. | +| shopping-management-C13 | State and concurrency | shopping-management-R5 | Given two shoppers buying the same remaining quantity, a revision conflict prevents duplicate fulfillment. | +| shopping-management-C14 | State and concurrency | shopping-management-R5 | Given a repeated receipt key, inventory contains one movement per receipt line. | +| shopping-management-C15 | Integration and recovery | shopping-management-R5 | Given a lost purchase response, retry returns the original purchase rather than a second session. | +| shopping-management-C16 | Adapters and persistence | shopping-management-R6 | Given a purchase session without prices or image, history still shows shopper, date and items. | +| shopping-management-C17 | Domain and configuration | shopping-management-R6 | Given a partial refund or correction, history records a linked correction rather than rewriting the original purchase. | +| shopping-management-C18 | UI and accessibility | shopping-management-R6 | Given a session detail view, quantities purchased and received are labeled separately. | +| shopping-management-C19 | Security and privacy | shopping-management-R7 | Given a read-only member attempting receipt, the backend denies the mutation. | +| shopping-management-C20 | UI and accessibility | shopping-management-R7 | Given cancellation of an unpurchased line, the UI explains remaining source demand before confirming. | +| shopping-management-C21 | Integration and recovery | shopping-management-R7 | Given partial success followed by retry, the response identifies saved purchase facts and retries only the missing stock post. | + +Every implemented first-party module starts with meaningful behavior tests. Target and proposed merge gate: 100% lines/statements/functions/branches where the selected tools expose those metrics, enforced separately across backend, frontend and integration code. Third-party/generated artifacts are distinguished from authored source; broad exclusions cannot hide untested logic. No application coverage currently exists. + +Inject deterministic clocks, IDs, provider fakes and transaction failures. Use semantic assertions alongside golden content, real adapter contracts and disposable HA integration environments. Add Google Chrome evidence from the owner's authorized local HA for real UX; it does not replace automated tests or unit coverage. CI Check runs the complete applicable suite for every PR update. + +## 15. Documentation and discoverability + +The following paths are explicit proposed documentation changes relative to the clean repository baseline; implementation source/test paths are intentionally not invented. + +| Path | Change | +|---|---| +| specs/shopping-management.md | create | +| specs/README.md | create | +| specs/_template.md | create | +| specs/catalog.json | create | +| specs/CATALOG.md | create | +| docs/architecture.md | create | +| docs/product-vision.md | create | +| docs/glossary.md | create | +| docs/decisions.md | create | +| docs/reference-investigation.md | create | +| docs/copilot-adoption.md | create | +| docs/operations.md | create | +| docs/user-guide.md | create | +| docs/contracts/home-assistant.md | create | +| docs/acceptance-plan.md | create | +| docs/roadmap.md | create | +| README.md | update | + +| Audience | Artifact | Required content | +|---|---|---| +| Member | [User guide](../docs/user-guide.md) | Normal path, defaults and state meaning | +| Administrator/operator | [Operations](../docs/operations.md) | Setup, permissions, recovery, backup and rollback | +| Contributor | [Architecture](../docs/architecture.md) | Boundaries and executable constraints | +| HA consumer | [Entity/service contract](../docs/contracts/home-assistant.md) | Stable schemas, semantics and error handling | +| Reviewer | [Acceptance plan](../docs/acceptance-plan.md) | Tests, coverage and human evidence | + +Link/path validation accompanies updates. Implementation changes update the owning SDD, catalog evidence, actual tests and user documentation together. + +## 16. Acceptance scenarios + +The Given/When/Then-equivalent observable scenarios in section 14 are the executable acceptance inventory. For each case, the given precondition and action must produce the specified result with state and side-effect assertions; tests are not implementation snapshots. + +Acceptance includes normal, alternative, invalid, duplicate, concurrent, partial, failure, recovery, security, localization and accessibility paths as allocated above. Human review verifies the primary-state examples on desktop/mobile and light/dark themes. Live acceptance remains pending until an implemented artifact is exercised; no result is inferred from the budget. + +## 17. Requirements traceability + +| Requirement | Cases | +|---|---| +| shopping-management-R1 | shopping-management-C01, shopping-management-C02, shopping-management-C03 | +| shopping-management-R2 | shopping-management-C04, shopping-management-C05, shopping-management-C06 | +| shopping-management-R3 | shopping-management-C07, shopping-management-C08, shopping-management-C09 | +| shopping-management-R4 | shopping-management-C10, shopping-management-C11, shopping-management-C12 | +| shopping-management-R5 | shopping-management-C13, shopping-management-C14, shopping-management-C15 | +| shopping-management-R6 | shopping-management-C16, shopping-management-C17, shopping-management-C18 | +| shopping-management-R7 | shopping-management-C19, shopping-management-C20, shopping-management-C21 | + +All requirement cases are reciprocal with section 14. Domain invariants are owned by pure policy, command/state rules by application use cases, provider behavior by adapters, and visible content by presentation; the boundary table in section 8 assigns these responsibilities. Evidence and user/operator documentation are linked in section 15. + +## 18. Implementation sequence + +1. Resolve the blocking decisions and review this contract before Ready for implementation. +2. Establish test harness, CI Check and architecture checks with the first source files. +3. Implement pure policies and their complete branch tests, then transactional use cases. +4. Add adapters, schema/error contracts, retry/race fixtures and both deployment wiring paths. +5. Build the accessible localized UI and HA projections with tests alongside each flow. +6. Verify migration, recovery, security, channel isolation and documentation. +7. Run the complete suite, review coverage, perform local Chrome dogfooding with recorded cleanup, and collect human evidence. + +These are internal implementation steps within the first integrated release; they do not remove other domains or deployment targets from launch. + +## 19. Definition of Done + +- [ ] Every normative requirement has observable acceptance and reciprocal case links. +- [ ] Every declared case is implemented meaningfully; the numeric budget is met. +- [ ] Clean Architecture constraints and port contracts pass. +- [ ] All supported first-party coverage metrics reach 100% from the first implementation. +- [ ] CI Check passes for the current PR revision with no omitted required jobs. +- [ ] Configuration, state, permission, idempotency and recovery behaviors agree. +- [ ] Primary UI states, localization, responsive behavior and accessibility pass. +- [ ] Both deployment targets and isolated Stable/Edge channels pass acceptance. +- [ ] User/operator documentation, schema/migration evidence and catalog paths are current. +- [ ] Local Google Chrome evidence identifies the artifact, channel, test records and cleanup. +- [ ] The original Copilot validations pass when their real prerequisites exist; no check is weakened. +- [ ] No material decision blocking readiness remains unresolved; Copilot remains unchanged. + +## 20. References and decisions + +Primary sources: [Copilot standard](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/README.md), [original template](https://github.com/vypdev/copilot/blob/f5e5a4cf9a80248994469cd88ad55eecab5b95ca/specs/_template.md), and the linked [reference investigation](../docs/reference-investigation.md). + +Confirmed owner choices and unresolved proposals are separated in [decisions](../docs/decisions.md). [Issue #2](https://github.com/vypdev/domus/issues/2) tracks the documentation foundation. The [adoption note](../docs/copilot-adoption.md) records the current catalog evidence limitation. Optional future depth remains explicitly deferred in the product vision; the gateway's installation and MCP internals are outside Domus scope.