← Back to directory

products-services-semantic-proposal.md

implementation/products-services-semantic-proposal.md · 13.0 KB · 2026-11-02 12:48

Products & Services Semantic Definition Proposal

Status: PROPOSAL — requires product-owner approval; not semantic authority Date: 2026-10-15

This document converts the current Products & Services implementation gap into an explicit approval proposal. It does not publish a Definition, change a capability profile, provision a Business, mutate STAGING or add a new architecture decision number.

The proposal follows the canonical owners:

Business scoping, authority, Policy and isolation.

1. Current-state evidence

Authoritative capability configuration

generic-business-capability-profile.json declares:

{
  "key": "products-services",
  "label": "Products & Services",
  "records": []
}

The persisted Business Presentation profile contains a generic Products & Services Presentation node, but it has no record collection or record editing binding. The deployed page therefore presents only the data-defined status text that record Operations are not configured.

Existing reusable Type

CapabilityCompositionVocabulary::OFFERING_TYPE already defines the Type:

a8100000-0000-4000-8000-000000000001

Its existing descriptor is:

| Property | Type | Required | |---|---|---:| | name | string | yes | | offering_kind | string | yes | | description | string | no | | lifecycle | string | yes | | commercial_context | string | no |

The descriptor rejects additional properties. It is installed through the existing capability-composition vocabulary and uses the universal Object/Type model. No new Product or Service Type is required by the current repository evidence.

Existing generic lifecycle mechanism

BusinessRecordService already validates configured record values against the persisted Type descriptor and submits create/update effects through the existing CommandHandler, with Business scope, expected versions, transaction handling, revisions and provenance.

BusinessPresentationProvisioningService already derives persisted Business-scoped View Definitions and Presentation Object graphs from the authoritative capability profile. It is the appropriate reconciliation owner for this record binding.

The repository does not establish a Product/Service-specific delete, archive, pricing, tax, inventory, fulfilment or service-delivery Operation.

2. Recommended semantic model

Recommendation: one Offering Type with a discriminator

Reuse OFFERING_TYPE for both products and services. The offering_kind property distinguishes the configured offering kind.

This is ESTABLISHED at the Type-structure level because the Type already exists and already contains offering_kind. The allowed values themselves are RECOMMENDED, not established business requirements.

Recommended initial values:

product
service

These values require approval before they become an authoritative validation vocabulary. Until approved, the Type's existing string validation remains the only established constraint.

Why this model is recommended

vocabulary.

Alternative: separate Product and Service Types

Not recommended. Separate Types would duplicate validation, Presentation, authorization targets and provisioning configuration without any established semantic distinction requiring different persistence or Operation contracts. Separate Types may become justified later only if approved requirements show different invariants or lifecycles that cannot be represented by the shared Offering Type.

Alternative: free-form capability fields

Rejected. A capability-local field map would bypass the universal Type contract and make validation, authorization and Presentation resolution capability-specific.

3. Proposed field schema

The following uses the existing Type descriptor; it does not add new runtime validation.

Essential fields

| Field | Established/recommended status | Presentation | |---|---|---| | name | ESTABLISHED by OFFERING_TYPE and required | Required text | | offering_kind | ESTABLISHED as a required string field; product/service values are RECOMMENDED | Required select after value approval, otherwise required text | | lifecycle | ESTABLISHED as a required string field; vocabulary is UNRESOLVED | Required text until lifecycle vocabulary is approved |

Optional fields

| Field | Status | Presentation | |---|---|---| | description | ESTABLISHED by the existing Type descriptor | Optional textarea | | commercial_context | ESTABLISHED by the existing Type descriptor | Optional textarea |

Explicitly excluded from this proposal

The following are not inferred or added:

Those concepts require separate requirements and semantic definitions if they become necessary.

4. Lifecycle proposal

The existing Type requires a lifecycle string but does not establish a controlled vocabulary or a transition model.

| Choice | Classification | |---|---| | Retain lifecycle as a required string field | ESTABLISHED by the existing Type | | Introduce draft, active, retired values | RECOMMENDED, requires approval | | Make lifecycle a state-transition definition | UNRESOLVED; requires approved State/Workflow semantics | | Add archive/delete now | NOT PROPOSED; no established Operation or retention requirement |

The minimum implementation should preserve the existing string field and avoid pretending that lifecycle values are authoritative until approved.

5. Operation and authorization matrix

| Capability | Mechanism | Status | |---|---|---| | Inspect Offering Objects | AuthorizedObjectReader through /objects | ESTABLISHED | | Create Offering Objects | Generic create effect through CommandHandler | ESTABLISHED | | Update Offering Objects | Generic update effect with expected version | ESTABLISHED | | Validate values | Existing Type descriptor and TypeDescriptorValidator | ESTABLISHED | | Delete | No Operation proposed | UNRESOLVED / deferred | | Archive | No Operation proposed | UNRESOLVED / deferred | | Product-specific Operation | None required for the minimum record lifecycle | ESTABLISHED by absence of requirement |

Business authorization must continue to require:

No direct repository write, special HTTP mutation path or Product/Service mutation handler is proposed.

6. Capability and Presentation configuration

Capability profile binding

The Products & Services entry should reference the existing Offering Type:

{
  "key": "products-services",
  "label": "Products & Services",
  "records": [
    {
      "key": "offering",
      "label": "Products & Services",
      "type_id": "a8100000-0000-4000-8000-000000000001",
      "view_id": "a2000000-0000-4000-8000-000000000004",
      "fields": [
        { "name": "name", "label": "Name", "renderer": "text", "required": true },
        { "name": "offering_kind", "label": "Product or service", "renderer": "text", "required": true },
        { "name": "description", "label": "Description", "renderer": "textarea" },
        { "name": "lifecycle", "label": "Lifecycle", "renderer": "text", "required": true },
        { "name": "commercial_context", "label": "Commercial context", "renderer": "textarea" }
      ]
    }
  ]
}

This is a proposed configuration shape, not yet an approved persisted change. a2000000-0000-4000-8000-000000000004 is a proposed unused View declaration identity and must be checked before implementation.

View Definition

The Business-scoped View Definition should use the same fields for list and detail presentation, with a shorter list:

pipeline

The existing reconciliation mechanism should derive and persist the View Definition and Presentation Object graph. No Products-specific renderer is permitted.

Form behavior

The existing generic object form can consume the persisted detail_fields binding. It should not introduce a Product-specific template. The form submits the existing generic create/update mutation path and preserves expected versions and provenance.

7. Provisioning and idempotency

Implementation, after approval, should:

1. Confirm or install the existing OFFERING_TYPE descriptor through CapabilityCompositionVocabulary::install. 2. Add the Offering record entry to generic-business-capability-profile.json. 3. Add the corresponding View declaration to generic-business-capability-configuration.json if that manifest remains the authoritative declaration source for the Business-scoped View. 4. Reconcile persisted View and Presentation Objects through BusinessPresentationProvisioningService. 5. Ensure the Business authorization target set includes OFFERING_TYPE. 6. Verify repeated reconciliation produces no duplicate Objects or revisions. 7. Verify a newly initialized Business can inspect, create and update Offering Objects only through canonical generic routes.

No records should be seeded merely to make the UI appear populated.

8. Decisions requiring approval

The following are the minimum unresolved product decisions:

1. Approve the shared OFFERING_TYPE model for both Products and Services. 2. Approve the product and service offering_kind values, or provide the authoritative vocabulary. 3. Approve whether lifecycle remains a free string initially or receives an approved controlled vocabulary. 4. Approve the proposed field labels and the proposed View declaration identity. 5. Confirm that pricing, currency, tax, inventory and service-delivery semantics are out of scope for this increment. 6. Confirm that delete/archive Operations are deferred.

No additional architecture decision number is needed. These are product configuration decisions under the existing settled Object, Business, Operation, Governance and Presentation contracts.

9. Implementation and regression plan

After approval:

Focused tests

Required validation

No STAGING database mutation is authorized by this proposal.