# Idiosyncrasy — Implementation Plan **Version:** 2.2 **Source basis:** Current Idiosyncrasy documentation at `https://docs.idiosyncrasy.co.uk/docs/` **Prepared:** 2026-09-13 **Status:** Implementation planning document; not evidence that any mechanism below has been built or verified. This is planning source material, not a canonical architecture owner, implementation contract or current status record. Use the following classification: | Classification | Location / authority | |---|---| | CURRENT | Section 24.1 executable dependency order, bounded by the canonical owners and current task scope | | COMPLETED | [Implementation status](status.md); this plan is not evidence | | NEXT | Only the explicitly requested bounded task; no stage is implied by this document alone | | DEFERRED | Sections marked Deferred/Later, the roadmap and current status limitations | | SUPERSEDED | Any earlier sequence or instruction that conflicts with section 24.1, a frozen implementation contract or current status | | HISTORICAL | The v2.0 backlog and historical planning inventories retained for traceability | Do not read this document in full for an ordinary implementation task. Read the relevant current section only, then the canonical owner, applicable implementation contract, development guidance and status evidence. Sections 25 onward contain mixed acceptance, guardrail, traceability and historical material; they do not override the classification above. --- ## 1. Purpose This document translates the current Idiosyncrasy documentation into a dependency-ordered engineering plan. The current documentation is the source of truth for the product and architecture. This document must not redefine the settled semantic contracts D01–D10. Where the documentation already chooses an implementation mechanism, that mechanism is adopted. Where it deliberately leaves an implementation detail open, this document chooses the smallest conforming mechanism necessary to build the first runtime. The initial implementation target is a **generic Business-scoped demonstrator**, operating on the generic Idiosyncrasy runtime. The goal is not to create or assume a Spearmint Design Business or build a conventional CRM first. The goal is to prove that a business can be represented, operated and extended through the universal runtime without bespoke business-code foundations. --- ## 2. Authoritative Source Hierarchy The implementation must follow the documentation authority model: 1. Current canonical product and architecture documentation. 2. Settled D01–D10 decisions. 3. Current product roadmap and capability definitions. 4. Current implementation documentation. 5. This implementation plan. 6. Existing/legacy code only as implementation reality and reuse evidence, never as the new domain model. The documentation explicitly distinguishes: - **settled semantic contract** — what Idiosyncrasy means; - **chosen implementation mechanism** — how the contract is initially implemented; - **current implementation status** — what has actually been built and verified. Implementation must preserve this distinction. ### Contract notation Each prescriptive addition in this plan uses these boundaries: - **Semantic Contract** states the settled platform meaning owned by the canonical architecture. - **Implementation Contract** states the smallest required mechanism for this runtime. - **Implementation Detail** may be chosen by an implementer without changing either contract. - **Deferred/Later** is intentionally outside the bounded runtime and must be refused or reported as unsupported. ### Primary documents - `product/definition.md` - `product/roadmap.md` - `product/capabilities.md` - `architecture/objects-and-types.md` - `architecture/business-model.md` - `architecture/semantics.md` - `architecture/time-and-events.md` - `architecture/workflows-and-automation.md` - `architecture/identity-and-governance.md` - `architecture/views-and-content.md` - `architecture/knowledge.md` - `architecture/retrieval.md` - `architecture/communication-and-integrations.md` - `architecture/analytics-and-evolution.md` - `architecture/ai.md` - `implementation/architecture.md` - `implementation/development.md` - `implementation/security-and-operations.md` - `implementation/ui-system.md` - `implementation/status.md` - `governance/decisions.md` - `governance/documentation.md` - `governance/source-map.md` Archived sources are provenance only and are not current build authority. --- ## 3. Owner Decisions Applied to This Build The project owner has explicitly selected the following implementation context: | Decision | Choice | |---|---| | Initial hosting | Existing web server/hosting | | Backend | PHP 8.3.33 | | Framework | None | | Database | MariaDB 10.5.26 / InnoDB | | Database access | PDO + `pdo_mysql` | | Dependency management | **No Composer; native autoloader owned by Idiosyncrasy** | | Autoloading | Native first-party PSR-4-style autoloader | | Frontend | Server-rendered UI with small JavaScript enhancements; frontend framework remains deliberately TBD | | Authentication | Owned by Idiosyncrasy | | Business context | Independent Business identity and governed Business-scoped isolation from foundation | | First demonstrator | Spearmint Design | | Runtime shape | Modular monolith, distribution-ready by contract | | Infrastructure | Smallest production-capable foundation; no premature microservices | | AI | Optional; platform remains useful without an AI provider | | Implementation detail | Near-executable practical specification, without prescribing every line of code | The current live implementation architecture aligns with PHP 8.3.33, PDO + `pdo_mysql`, MariaDB 10.5.26/InnoDB, an explicit composition root, a modular monolith, server-rendered presentation and small JavaScript enhancements. No application framework or Composer is used. PSR-4-style namespaces and autoloading may still be used, but autoloading is implemented by a small first-party bootstrap loader. --- # 4. Non-Negotiable Architectural Constraints ## 4.0 Platform Governance Foundation Build Slice The first build slice implements explicit platform/business scope within the universal model. It reuses AuthorityGrant, Policy, Operation, the trusted handler registry and one CommandHandler. Platform authority is direct User authority with no Membership and no Business; Business authority remains Membership-bound and scope-local. The trusted `business.create` handler generates Business and initial governance identities, and the platform Command branch persists its Command/evidence record with the nullable platform evidence scope. The bounded User admission Operations (registered as `principal.register` and `principal.confirm`, legacy identifiers for the User registration and confirmation Operations) use the same governed Command boundary; broader platform mutation coverage remains outside this slice. ## 4.1 Universal semantic model All persistent and addressable platform data uses: ```text { id: , type: , value: } ``` This applies to business objects, types, relationships, configuration, knowledge, permissions, workflows, workflow nodes where independently addressable, events, views, policies, commands, executions and other addressable concepts. No capability may introduce a competing foundational data model. ## 4.2 Physical database is not the semantic model The universal model does **not** require a single SQL table, EAV storage, graph database or JSON-only database. The approved initial physical mechanism is a dedicated MariaDB database with relational support structures and typed JSON values. The database implements the logical model; it does not redefine it. ## 4.3 One Business Graph Business data, definitions, configuration, workflows, knowledge, events, permissions and other addressable concepts participate in one connected model. A Customer reused by CRM, projects, marketing, forms and reporting remains the same addressed object. Connectivity does not grant authority and graph traversal does not itself infer semantic truth. ## 4.4 Authority is explicit Authentication, user identity, Business context, membership, AuthorityGrant, Policy, approval and technical execution identity remain distinct. A business relationship must never silently become permission. ## 4.5 Deterministic runtime Core operations must function without AI. AI output is an input/proposal subject to the same validation, authorization and approval boundaries as human-authored changes. ## 4.6 Command-centred mutation All consequential mutations use one authoritative Command pipeline. HTTP, UI, workflow, CLI and AI adapters must not create alternative mutation paths. Repositories are storage mechanisms, not public mutation endpoints. ## 4.7 Durable authority Committed database state is authoritative. Caches, read models, indexes and in-memory state cannot certify a mutation or override durable versions. ## 4.8 Explicit concurrency Updates use expected versions. Stale updates are rejected. There is no last-write-wins fallback. ## 4.9 Explicit Unknown/Reconciliation A lost response after possible commit is not treated as failure. Unknown external outcomes are not automatically repeated. ## 4.10 No arbitrary runtime code generation Business behaviour is represented through types, configuration, policies and controlled workflows. Generated configuration is not arbitrary generated PHP. --- # 5. Initial Runtime Architecture ## 5.1 Deployment shape Use a single deployable PHP application initially. ```text Web Server | v PHP Front Controller | v HTTP Controllers | v Application / Command Services | +---- Validation +---- Business Context +---- Authority / Policy +---- Workflow +---- Retrieval | v Repositories / Persistence Adapters | v MariaDB 10.5.26 / InnoDB ``` A later distributed deployment may separate responsibilities, but no semantic contract may depend on process boundaries. ## 5.2 PHP structure Use: - PHP 8.3.33 - native first-party autoloading - PHP namespaces following PSR-4-style directory conventions - explicit composition root - PDO with the `pdo_mysql` driver - `App\Runtime` namespace for the new platform runtime - constructor injection where practical - explicit registration of supported validators, action handlers, adapters and view renderers Do not wire old direct-SQL controllers into the new runtime. ## 5.3 Suggested repository structure ```text /app /Runtime /Auth /Business /Commands /Objects /Types /Relationships /Policies /Events /Workflows /Knowledge /Retrieval /Views /Content /Integrations /Analytics /AI /Governance /Persistence /Http /Presentation /Legacy # existing code, isolated and not authoritative /bin bootstrap.php dispatch.php ... /config /database /migrations /seeds /tests /Unit /Integration /Concurrency /Security /Acceptance /public /assets /docs ``` The exact directory grouping may be adjusted during implementation if it preserves the responsibility boundaries. The fourteen conceptual responsibilities do **not** require fourteen PHP modules/services. ## 5.4 Legacy Isolation and Target Cutover **Semantic Contract:** legacy code cannot become an alternative authority for target-runtime business state. **Implementation Contract:** the target runtime has a distinct front controller/public entry point, fresh dedicated database, session cookie name and runtime configuration namespace. Its routes use only `App\Runtime` services and the new database. Target routes never invoke legacy controllers, repositories, tables, setup scripts or mutation paths. The legacy application may remain reachable during development only through a segregated legacy deployment or hostname/path with its existing database and its own session cookie. There is no old-data migration. Before target release, deploy only the target entry point and target routes at the production runtime location. Disable or remove legacy routing from that entry point; a reverse proxy/path rule may direct an explicitly retained legacy environment elsewhere, but it must not share target sessions or database credentials. Reusable legacy material is limited to reviewed visual tokens, narrow PHP/PDO configuration lessons and isolated helper patterns. It must be copied/refactored behind the target boundary, never called as a target mutation dependency. **Implementation Detail:** the exact hostname, path prefix, deployment directory and session-cookie names may be chosen for the host, provided the two applications remain isolated. **Deferred/Later:** migration, compatibility endpoints, mixed-record views and gradual record-by-record conversion are not in scope. --- # 6. Physical Persistence and First-Slice Database Contract Create a **fresh dedicated database** for the new runtime. Do not use the old marketing schema as the foundation and do not create a migration/compatibility layer unless separately requested. ### Native autoloading policy Composer is deliberately excluded. The application owns its bootstrap and class loading. Use PHP namespaces with a PSR-4-compatible directory convention, but implement the loader in a small first-party file such as `bootstrap/autoload.php`. The loader must: - map the application namespace to `/app`; - reject path traversal or malformed class names; - load only `.php` files under approved application roots; - fail clearly when a required class cannot be loaded; - remain independent of any package manager; - be covered by a smoke test. Do not recreate Composer's package-management functionality. We only need class loading for the first-party application. ### Native test bootstrap **Implementation Contract:** PHPUnit 11 is used without Composer on PHP 8.3.33. PHPUnit 11 requires PHP 8.2 or newer, so the selected major version is compatible with the production CLI; the exact patch release must still be pinned and smoke-tested against PHP 8.3.33. The repository stores the pinned PHAR under `tools/`, with the exact version and SHA-256 recorded in a sibling checked-in metadata file. Test bootstrap requires the same first-party runtime autoloader. The executable test command is: ```text php tools/phpunit-11.phar --bootstrap tests/bootstrap.php tests ``` The acquisition/refresh procedure verifies the recorded SHA-256 before replacing the PHAR. The test command, PHP version and MariaDB fixture configuration are recorded as evidence when the suite first runs. **Implementation Detail:** the exact PHPUnit 11 patch release and download procedure may be selected during the foundation task, then locked by version and hash. **Deferred/Later:** Composer, Composer scripts and dependency-managed test packages are excluded. ### MariaDB 10.5 compatibility boundary **Implementation Contract:** all SQL and DDL must run against MariaDB 10.5.26 with InnoDB. The implementation may use enforced `CHECK` constraints, `DATETIME(6)`, unsigned integer versions, InnoDB row locks, named advisory locks and `INSERT ... ON DUPLICATE KEY UPDATE`, subject to focused execution checks on the production-compatible server. JSON values use MariaDB-compatible JSON text semantics; do not rely on MySQL binary-JSON behavior, MySQL 8-only functions or MySQL-only DDL shortcuts. Generated columns/indexes may be used only for declared scalar filters after MariaDB verification. Migration atomicity must be determined per MariaDB 10.5 statement rather than assumed from MySQL behavior. The forward-only migration ledger, checksum verification and tested repair path remain required for any non-transactional DDL. ## 6.1 Authoritative object rows **Semantic Contract:** all persistent/addressable concepts remain universal objects. A relational support table never becomes a competing domain model. **Implementation Contract:** use the following first-slice tables. All identifier columns are `CHAR(36) CHARACTER SET ascii COLLATE ascii_bin`; all recorded timestamps are `DATETIME(6)` in UTC; versions are `BIGINT UNSIGNED`; all tables are InnoDB with MariaDB-compatible `utf8mb4` JSON/text values. | Table | Required columns | Keys and constraints | Purpose | |---|---|---|---| | `objects` | `id`, `type_id`, `type_revision`, `scope_kind`, nullable `business_id`, `version`, `lifecycle`, `value_json`, `created_recorded_at`, `updated_recorded_at` | PK `id`; `version >= 1`; `scope_kind` is `platform` or `business`; check that platform rows have no Business and business rows have one; index `(business_id, type_id, lifecycle, id)` | Authoritative current typed state. `lifecycle` is only `active` or `retired` at this layer; business State remains a typed reference in `value_json`. | | `object_revisions` | `object_id`, `version`, `type_id`, `type_revision`, `lifecycle`, `value_json`, `recorded_at`, nullable `command_id`, nullable `provenance_id` | PK `(object_id, version)`; FK `object_id -> objects.id ON DELETE RESTRICT`; index `(type_id, type_revision)` | Immutable retained representation of every committed object version, including version 1. | | `event_index` | `event_id`, `business_id`, `event_type_id`, nullable `subject_id`, nullable `command_id`, nullable `causation_event_id`, nullable `correlation_id`, `occurred_at`, `recorded_at`, auto-increment `sequence` | PK `event_id`; unique `sequence`; indexes `(business_id, event_type_id, sequence)` and `(command_id)` | Query support for canonical Event objects. Event payload and provenance remain in the Event object's typed value. | | `transition_index` | `transition_id`, `subject_id`, `business_id`, nullable `before_state_id`, `after_state_id`, `subject_version`, `command_id`, `recorded_at` | PK `transition_id`; indexes `(subject_id, subject_version)` and `(business_id, recorded_at)` | Query support for canonical state-transition occurrence objects. | `objects.type_id`, `objects.business_id`, and typed references inside `value_json` deliberately have no database foreign keys to `objects`: the root self-describing Type and mutually-referencing genesis graph cannot be inserted under those foreign keys. The Type validator and controlled-manifest validator must resolve them before normal commit and before genesis commit respectively. Support tables use restrictive foreign keys where the referenced current object can already exist. No object row is hard-deleted in the first slice. **Implementation Detail:** column order, generated names for check constraints, and JSON serialization implementation are not architectural choices. JSON is retained as typed object value; the only first-slice JSON fields eligible for indexed retrieval are declared scalar properties in the active Type revision, materialized as generated columns/indexes only when a declared list filter needs them. **Deferred/Later:** type-family inheritance, arbitrary JSON-path indexes, partitioning, full-text/vector indexes, bitemporal storage and hard-redaction jobs are not initial mechanisms. ## 6.2 Governance, execution and derived support rows **Implementation Contract:** these support structures protect the universal model; their rows are not a second semantic foundation. | Table | Required columns and constraints | Purpose | |---|---|---| | `credentials` | `principal_id` PK/FK to `objects.id` (legacy identifier for the User), `password_hash`, `password_changed_at`, nullable `disabled_at`; hash is never selected by generic object retrieval/export | One password credential per registered User, subject to confirmation and lifecycle state. | | `auth_rate_limit_buckets` | PK `(scope, subject_hash, window_started_at)`; `attempt_count`; fixed 15-minute UTC windows; increment atomically with one `INSERT ... ON DUPLICATE KEY UPDATE` | Durable five-failures-in-15-minutes control for separately hashed user and source-address subjects. | | `command_keys` | `command_id` PK/FK to Command object; `principal_id`, `business_id`, `operation`, `fingerprint BINARY(32)`, `admitted_at`; command ID is globally unique | Binds a stable Command identity to exactly one canonical semantic request. A repeat ID must match every bound value and fingerprint or is a conflict. | | `relationship_index` | `relationship_id` PK/FK; `business_id`, `relationship_type_id`, `source_id`, `target_id`, `active`; indexes in both endpoint directions | Transactionally maintained derived traversal structure. Never an authority source. | | `relationship_slots` | PK `(relationship_type_id, endpoint_role, endpoint_id, slot)`; `relationship_id` unique; a slot exists only while a max-one relationship is active | Enforces initial `0..1` cardinalities, including one active Project originating from one Qualification. | | `workflow_trigger_keys` | PK `(event_id, workflow_id, workflow_revision)`; `workflow_execution_id` unique | Ensures one committed Event starts at most one execution of an applicable active workflow revision. | | `workflow_dispatch` | `workflow_execution_id` PK/FK; `dispatch_state`, `eligible_at`, nullable `lease_token`, nullable `leased_by`, nullable `lease_expires_at`, `step_count`, nullable `last_error_code`; eligibility index `(dispatch_state, eligible_at, workflow_execution_id)` | Durable dispatcher eligibility and lease state for canonical WorkflowExecution objects. | | `runtime_coordination` | exactly one seeded row `id = 1` | Every normal consequential mutation locks this row with `SELECT ... FOR UPDATE` before final validation. It serializes the first runtime across PHP processes. | | `schema_migrations` | `migration_id` PK, `checksum BINARY(32)`, `applied_at`, `release_id` | Migration ledger. The runner takes a named database advisory lock, verifies each applied checksum, applies one forward-only migration transactionally where the specific MariaDB 10.5 DDL permits, and records it only after success. | For the first slice, the coordination-row lock gives a single ordering for normal mutation, governance change, cardinality reservation and required history writes. Reads do not acquire it. External calls never run under it. A transaction rolls back every local state, revision, index, event, transition, Command/Attempt and success record if any required write fails. **Implementation Detail:** generated-column names, advisory-lock timeout, exact error-code strings and repository method names are local choices. A migration whose DDL cannot be transactionally reversed must be explicitly marked non-transactional and have a tested forward repair; it may not be silently retried. **Deferred/Later:** sharded coordinators, row-level fine-grained lock optimization, generalized cardinality above `0..1`, asynchronous indexers and online schema-change tooling. ## 6.3 Supporting typed objects These remain addressable platform objects even where physical support structures exist: - Type - State definition - Business - Membership - AuthorityGrant - Policy - Decision - Relationship - Assertion - Command - Action Execution - Attempt - transition occurrence - provenance - Workflow - Workflow Execution - View definition - Knowledge item - Integration configuration A support table exists to make the runtime safe and efficient; it does not become a competing semantic universe. ## 6.4 IDs and time - UUIDv4 opaque addresses - `CHAR(36)` representation - binary comparison - unsigned integer versions - UTC microsecond timestamps - explicit timezone names for business scheduling - half-open effective intervals ## 6.5 Indexing Initial indexes should support: - `(business_id, type_id, id)` - relationship endpoints/type/direction - revision identity - command identity/fingerprint - workflow eligibility/lease state Use stable ID cursor pagination. Default page size: 50. Maximum initial page size: 100. Authority filtering occurs before disclosure. No asynchronous search index is required initially. --- # 7. Object and Type Runtime ## 7.1 Type definition A Type is itself an addressable object. A type definition must be capable of describing: - semantic identity - display name/label - properties - required/optional values - scalar/nested value validation - permitted relationships - applicable State definitions - permitted state transitions - permission declarations - ownership requirements - supported UI representation - supported workflow capabilities - type-family metadata where later supported - revision/version Unsupported inheritance/composition must be rejected rather than guessed in the first runtime. ## 7.2 Definition revision lifecycle **Semantic Contract:** Types, Policies, Workflows, Views and Business DNA are addressable versioned configuration; a later definition must not rewrite prior use. **Implementation Contract:** each configuration object has immutable retained revisions in `object_revisions` and one current object row. Initial configuration lifecycle is `draft -> active -> retired`. A Business-scoped configuration item has at most one active revision for its object identity; activation is a governed Command that retires no historical revision. A new active revision supersedes the former current revision only for future selection. Restoration creates a new revision whose value references the restored source revision; it never mutates historical rows. Instances bind `type_id` and `type_revision` at creation. They continue to validate and render against that revision until an explicit, validated upgrade Command creates a new instance revision. Workflow executions pin their Workflow revision; Actions, Decisions and transitions record each relevant Type, Policy and Workflow revision. Retiring a definition prevents its selection for new work, but does not erase existing instances, history or pinned executions. A changed dependency is rechecked before a pending workflow continuation; it either remains applicable, suspends for review, or requires a new Decision. No implicit workflow migration occurs. **Implementation Detail:** the exact revision-number allocation, API shape and editor layout may be chosen locally. **Deferred/Later:** concurrent branching/merging, type inheritance, bulk instance upgrades and automated compatibility migration are refused. ## 7.3 Validation Every object entering the runtime must pass deterministic validation. The same validation boundary applies to: - human input - imported data - workflow actions - CLI/bootstrap operations - automated proposals - AI proposals Validation does not grant authority. Authority does not make invalid data valid. ## 7.4 State identity Keep these separate: 1. State definition 2. Current state reference on an object 3. State-transition occurrence A label such as `approved` is not itself a State identity. Historical transitions retain the State definition/revision context used at the time. ## 7.5 Object lifecycle For the demonstrator, prefer retirement rather than hard deletion where historical references matter. Historical references must remain explainable subject to authorization and retention rules. --- # 8. Business Graph and Relationships Relationships are first-class addressable objects when they require independent identity, metadata, lifecycle, provenance or history. Scalar references that do not require independent identity may remain typed values. Relationship Types must define: - permitted source type(s) - permitted target type(s) - direction - cardinality - role semantics - lifecycle constraints - integrity constraints Relationship mutation must validate: - endpoint existence - endpoint accessibility - endpoint type compatibility - Business/isolation boundary - relationship type - cardinality - required metadata - applicable Policy/authority - expected versions A relationship never grants permission merely because it exists. Relationship history and temporal meaning follow the Time/Event contract. --- # 9. Identity, Authentication and Business Context ## 9.1 Authentication Implement server-side PHP sessions using: - `password_hash` - `password_verify` - session ID regeneration after authentication - Secure/HttpOnly/SameSite cookies - CSRF protection - durable rate limiting - HTTPS enforcement at the deployment boundary The target runtime begins with User registration and confirmation; the existing login-only slice is historical/reuse material and does not satisfy that admission lifecycle. **Implementation Contract:** password credentials use Argon2id through PHP's password API, have a 14-character minimum and are rehashed on successful login when PHP reports that they are outdated. Login returns a generic failure response, performs a dummy verification for an unknown identity, and checks atomic identity-hash and source-address-hash rate-limit buckets. After successful CSRF validation, every login attempt entering authentication participates in the existing source-address accounting, including malformed or noncanonical identity input. Identity-specific accounting applies only when a canonical User UUID is available; malformed input must never create, access or mutate an identity bucket. Canonical unknown UUIDs receive identity and source accounting, while valid-but-unconfirmed noncanonical identities receive source-only accounting. A successful password authentication regenerates the session identifier. Target sessions use Secure, HttpOnly and SameSite=Strict cookies, a target-only cookie name, a 30-minute idle lifetime and an eight-hour absolute lifetime. Logout, credential disablement and password change invalidate the current session; a subsequent request must reload the credential and membership state rather than trust a cached session grant. The first runtime supports password assurance only. A configured operation requiring stronger assurance is refused until its assurance mechanism exists. Registration and confirmation are implemented as separate narrowly bounded pre-authentication admission Operations; password recovery, SSO and MFA enrollment remain outside this initial contract unless separately approved. ## 9.2 Identity distinctions Keep distinct: ```text Authentication identity | v User (authenticated account) | v Business membership | v AuthorityGrant | v Operation / target ``` A Person, Organisation or Business object is not automatically an authenticated User; a Person is a Business-scoped individual profile, and neither a User nor a Person requires the other. ## 9.3 Business-scoped isolation and entitlement Independent Business identity and Business-scoped isolation exist from the beginning. This is an isolation and authority boundary, not a fixed ownership or tenant model. Every Business-scoped read/write/retrieval/relationship/file/integration operation must resolve and enforce Business context. Business-scoped operational execution must also satisfy the canonical subscription entitlement gate in [subscriptions and entitlements](../architecture/subscriptions-and-entitlements.md) (intended future architecture; all Businesses are currently treated as active and no entitlement is enforced). `business.create` is free and never entitlement-gated. This implementation plan does not define a second subscription mechanism. Business selection is a context selection, not a grant. ## 9.4 Initial UI identity flow ```text Login ↓ Authenticated User ↓ Authorised Business list ↓ Business context ↓ Application UI ``` The first Idiosyncrasy bootstrap Business does not automatically grant access to Spearmint. **Implementation Contract:** a credential authenticates one User. An active Membership grants selection of a Business context only; a separate active AuthorityGrant authorizes named operations against declared object Types, object IDs or configuration scopes. Every read, mutation, history lookup, relationship traversal, export, file access and workflow continuation resolves the User and current Business server-side. Platform-scoped definitions are not publicly readable by default and need an explicit platform/configuration grant. Cross-Business sharing is unsupported and denied. --- # 10. Authority and Policy Policies are versioned typed objects with: - scope - effective interval - conditions - composition references - provenance The initial expression interpreter supports only an allowlisted deterministic language: - typed equality - membership - numeric comparisons - Boolean `all` - Boolean `any` - Boolean `not` Never use `eval` or arbitrary generated code. Unknown/missing input is not a successful condition. A Policy relationship does not automatically establish precedence. When conflict cannot be deterministically resolved, stop the effect and create a scoped human Decision request. A Decision: - records the authorised human determination - preserves rationale/provenance - cannot grant missing authority - cannot bypass type validation - cannot become an unexplained global override Exceptions/delegations are explicit typed arrangements with scope, period, conditions and provenance. **Implementation Contract:** an Approval is a Decision object that binds the proposal/action identity, Business, target object IDs and revisions, Policy revisions, determination, approving User and optional expiry. The approver must hold current approval authority at Decision commit and again when the approved Action commits. Email links, notification reads and an asserted user ID are not approval. Delegation is represented and audited but no onward delegation is supported in the first slice. Revocation, retirement or changed dependencies invalidate future use after commit-time recheck, never past evidence. A worker records a distinct technical executor identity as execution provenance only; it has no independent authority, and business authority derives from the authority delegated by a User (see [delegated authority for automation](../architecture/identity-and-governance.md#delegated-authority-for-automation)). **Deferred/Later:** role-group management, delegated chains, MFA, recovery, SSO, service-account APIs and cross-Business sharing. --- # 11. Command and Mutation Pipeline This is the central runtime path. ```text HTTP / UI / Workflow / CLI / AI | v CommandHandler | Authentication | Business Context | Type Validation | Authority | Policy | Expected Version Checks | Transaction / Commit | Revision + History + Provenance | Command Result ``` ## 11.1 Command identity Every consequential operation receives a stable Command ID. Canonicalize the semantic request by: - recursively sorting object keys - preserving array order - preserving scalar types - excluding transport metadata Hash the canonical representation with SHA-256. Bind it to: - operation - targets - expected versions - payload - user - Business ## 11.2 Admission In a short transaction: 1. lock the coordination row; 2. validate admission authority; 3. create/verify unique Command identity; 4. create Command object; 5. create Action Execution; 6. create initial Attempt/provenance; 7. detect duplicate versus conflicting request fingerprint. ## 11.3 Commit Reload authoritative state and governance dependencies. Recheck: - authority - Policy - expected versions - type validity - relationships - applicable configuration Perform all required local mutations in one transaction. Update with expected-version predicates: ```sql WHERE id = :id AND version = :expected_version ``` A zero-row update is stale/incompatible. Never silently fall back to last-write-wins. ## 11.4 HTTP contract Mutation endpoint: ```text POST /commands ``` Command status: ```text GET /commands/{id} ``` Initial response semantics: - `401` authentication required - `403` authenticated but denied - `422` invalid payload - `409` stale version or Command identity/content conflict - `202` admitted but unresolved/unknown with reconciliation state - `200` successful terminal result - `503` infrastructure failure before admission Do not expose inaccessible object existence through error differences. ## 11.5 First-milestone execution records **Semantic Contract:** Command, Action Execution, Attempt, Outcome, Event, state-transition occurrence and Provenance remain distinct addressable concepts. **Implementation Contract:** a Command is the semantic request; it has one Action Execution in the first local runtime. A Command and its Action Execution use lifecycle `admitted -> executing -> settled` or `admitted/executing -> reconciliation_required`. An Attempt records one try with `started -> settled`; every retry creates another Attempt. An Outcome is a separate addressable object linked to the settled Attempt and uses exactly one of `succeeded`, `rejected`, `failed` or `unknown`. `unknown` moves the parent Command and Action Execution to `reconciliation_required`; an authorised reconciliation Command records later evidence and a new Outcome without deleting the unknown Attempt. The first Command envelope contains `id`, `operation`, `business_id`, `targets`, `expected_versions`, `payload`, `source`, and canonicalization version `1`. The server supplies authenticated user, technical executor and correlation identifier; client payload cannot supply them. Canonicalization recursively sorts object keys, retains array order and scalar type, rejects duplicate keys, non-finite numbers and unsupported values, then encodes with one documented PHP JSON flag set before SHA-256 hashing. Existing changed targets require an expected version. Creates require a requested new object ID; an existing ID is a conflict. A multi-object Command lists expected versions for every pre-existing changed target. New IDs generated during first execution are stored in the Command result and reused when its stable Command ID is redelivered. An Event is a canonical addressable occurrence, not a request or a notification. First-milestone Events are required for object creation, declared State transitions, Qualification Decisions, workflow start/resume and Command reconciliation. `object.create` emits exactly one `object.created` Event in the same atomic commit as the new object, revision, provenance and required Command evidence. The Event records the addressable object creation occurrence through the existing Event object, Event Type and `event_index` infrastructure; it does not introduce a second Event or audit architecture. Authorization for `object.create` targets the requested object's Type within the server-resolved Business/configuration scope, using the existing operation-plus-target-Type AuthorityGrant model with current server-resolved Membership, Business and Policy checks. The new object identity is not itself an authorization target before creation, and request/manifest claims or relationships cannot grant authority; its stable identity is retained in the resulting Command, provenance and evidence. Each Event has a stable Event Type object reference, Business, subject references, occurrence/recorded time, provenance, optional causation Event and correlation identifier; `event_index` supplies a durable sequence for deterministic scanning. A declared State change creates one addressable transition occurrence with before/after State-definition references and one corresponding `object.transitioned` Event in the same local transaction. `object.update` and `object.relate` retain the generic policy that an ordinary value update or relationship operation emits an Event only when the declared operation requires one. The Command commit creates required revision, provenance, transition and Event records atomically with the business effect. A workflow consumer claims a committed Event by inserting `workflow_trigger_keys` in the same coordination-locked transaction; unique-key conflict means it was already admitted. Consumers record their own execution outcome and never treat Event delivery as proof of an external Effect. Current object rows remain authoritative: this is not event sourcing and Events are not used to reconstruct state by default. **Implementation Detail:** enum storage, error-code wording, JSON flags and internal class names may vary only if the canonical bytes remain stable for canonicalization version `1` and tests prove duplicate handling. **Deferred/Later:** event broker, cross-process subscription service, global causal ordering, arbitrary replay and exactly-once external delivery. --- # 12. Events and History Events, transition occurrences, Commands, Attempts and outcomes remain distinct concepts. Required history must be committed coherently with the state change. Historical records preserve: - actor/source - relevant definition versions - before/after state where applicable - provenance - recorded time - effective time where relevant - Command/Attempt identity A correction must not silently rewrite the historical meaning of a prior event. Events are available to workflows without requiring capability-specific event models. The event and transition records specified in section 11.5 are the required first implementation depth. They must be authorization-filtered on inspection and retain references even when related current objects are retired. They do not require a general activity feed, notification service or event-sourced projection system. --- # 13. Workflow Runtime ## 13.1 Definitions A Workflow Definition is an addressable, versioned configuration object. Keep separate: - Workflow Definition - Workflow Step/node - Workflow Execution - Action - Action Execution - Attempt - Outcome - Effect - Event - Trigger - Schedule - Job - Automation **Implementation Contract:** a Workflow Definition follows `draft -> active -> retired`; only one active revision of the selected workflow is eligible for a trigger. Draft definitions are inspectable only by authorized configuration users and never dispatch. Retirement prevents new trigger admission while retained executions remain pinned to their recorded revision. ## 13.2 Initial supported execution The first interpreter supports: - one Event trigger at a declared Event Type and subject relationship - sequential `condition`, `wait_for_event`, `request_approval`, `local_command` and `end` nodes - explicit named true/false continuation from `condition` - local mutation Actions through a stable Command ID - human approval represented by a governed Decision Command - deterministic State transitions Unsupported node types must be rejected rather than silently approximated. Each node has a stable node address within its pinned definition revision, one declared input binding, explicit permitted output/continuation names and no implicit controller order. `condition` uses the allowlisted Policy expression language and treats unknown/missing input as non-success. `wait_for_event` records event type, correlated subject/execution reference and optional UTC wake time; a matching committed Event resumes only that execution. `request_approval` records the proposed subject/version, required action, applicable Policy/version and permitted reviewer scope, then waits for a Decision Event. `local_command` identifies one exact approved Operation Contract identity and revision and maps only declared workflow inputs to that Command envelope. The Operation Contract is interpreted by its fixed trusted handler; the node does not supply executable behavior or a caller-defined effect list. ## 13.3 Execution persistence A WorkflowExecution records: - workflow ID - pinned workflow revision - Business context - input references - current node - dependency references - Action Executions - results - execution state - claim/lease information - error/reconciliation information ## 13.4 Dispatcher Initial mechanism: - CLI dispatcher - same CommandHandler used by web/API - database-backed claim - 60-second renewable lease - restart/resume support - current authority/dependency rechecks - no mandatory message broker - no automatic retry of unknown external effects One dispatcher pass is limited to 100 steps. Cycles or exhausted bounds result in a suspended/review-required state. **Implementation Contract:** WorkflowExecution uses `eligible`, `running`, `waiting`, `succeeded`, `failed`, `cancelled`, `suspended` or `reconciliation_required`. A dispatcher claims only `eligible` executions by assigning a fresh lease token and 60-second expiry. Every update from a worker includes that token; an expired/changed token fences the previous worker. The intended dispatcher command is `php bin/runtime-dispatch.php --once`; production cron will invoke that command at least once per minute using the same release and a distinct technical worker identifier once the dispatcher is implemented. The current repository does not yet contain that command. The process makes no external call in the first workflow. An unexpected process failure leaves the execution eligible after lease expiry only after the dispatcher reconciles the durable Command/Attempt record. It may create a new Attempt only for a local Command that has no settled Outcome; duplicate Command handling then prevents another semantic effect. Validation, denial and terminal failure are not automatically retried. An authorized cancellation Command may cancel an `eligible` or `waiting` execution before its next local Action; cancellation after an Action has started requires reconciliation and cannot erase prior effects. Every pass has a 100-step bound; a loop, exhausted bound, changed required dependency or unsupported continuation becomes `suspended` with an inspectable reason. **Deferred/Later:** parallel branches/joins, recurrence, arbitrary timers, priority queues, workflow migration/re-entry/compensation, live integrations and automatic retry of unknown remote effects. ## 13.5 Scheduling Initially support: - explicit UTC wake times - human-decision waits - one-time scheduled continuation For local-time scheduling: - require named timezone - reject nonexistent DST times - reject ambiguous DST times until an unambiguous instant is supplied Do not implement a general recurrence language initially. --- # 14. Retrieval Structured retrieval is a platform capability, not an AI-only feature. Initial retrieval must support constraints involving: - Business - type/type family - relationships - state - time - provenance - ownership - permission Apply authorization before disclosure. Use direct authoritative MariaDB-compatible queries initially. No vector database is required. Optional semantic retrieval may later narrow candidates but cannot bypass structural authorization or replace deterministic retrieval. Pagination: - cursor-based - stable ID ordering - default 50 - maximum 100 initially ## 14.1 First-milestone retrieval contract **Semantic Contract:** Retrieval is authorized structured context assembly, not an AI-only search service. **Implementation Contract:** before the first UI, implement only the governed Business identity projection used by Business selection, `getObject(id)` and `listObjects(business, type, cursor, pageSize)` plus declared Relationship traversal from an already authorized object. The Business identity projection resolves authorized active Memberships and returns permitted Business identity fields; it is distinct from ordinary Business-scoped object retrieval because the Business root is platform-scoped with `business_id = null`. `getObject` returns an authorized current object projection or the same non-disclosing absence result for inaccessible/nonexistent objects. `listObjects` requires an active Business context and Type ID, filters to active Business-scoped rows, applies field/relationship visibility before projection, orders by opaque object ID ascending and accepts an exclusive last-ID cursor. Page size defaults to 50 and is capped at 100. No arbitrary JSON-path query, free-text search or client-selected SQL sort is supported. A Type/View declaration may opt a named scalar property into a list projection only after that property is validated and its generated-column index is added by a migration. Relationship selectors call the same authorized list/traversal operations; they never load a global label list. The first history view resolves a known object/revision by ID under the same authority checks rather than supporting general historical search. **Implementation Detail:** SQL layout, repository method names and projection DTOs may vary. **Deferred/Later:** type-family query, cross-type filtering, arbitrary property/range/time/provenance/ownership search, full-text/vector search, aggregates and saved queries. --- # 15. Knowledge Knowledge is first-class addressable data in the same model. A document is a source, not automatically truth. Knowledge must retain: - source identity - provenance - authority/standing - contextual applicability - historical identity - relationships to relevant business objects Initial implementation should deliberately avoid automated document extraction as a prerequisite. Start with: - manual text capture - source reference - knowledge object - relationship to business objects - authorized retrieval AI question answering is optional. --- # 16. Views, UI and Presentation ## 16.1 Core principle The UI is a projection of the model, not a separate business model. ```text Identity ↓ Business Context ↓ Authorised Object/Type Model ↓ View Definition ↓ Server-rendered UI ↓ Small JS enhancement ``` The first implementation intentionally avoids locking the project into React/Vue/etc. The live specification explicitly calls for server-rendered view definitions with an allowlisted field/renderer registry and small JavaScript enhancements. ## 16.2 Initial screens The first usable runtime should include: 1. Login 2. Logout 3. Business selection 4. Business dashboard/application shell 5. Typed object list 6. Object detail 7. Declared operation form 8. Revision/history inspection 9. Transition/provenance inspection 10. Command status ## 16.3 UI safety All mutations go through Commands. Hidden/disabled controls are not security boundaries. Browser requirements: - CSRF on all mutations - accessible labels - keyboard operation - focus management - pending states - validation states - authorization-denied states - unavailable states - partial failure states - stale data messaging - duplicate-submission protection AJAX is preferred for non-navigation actions, with safe conventional form fallback where practical. ## 16.4 First-milestone generic view/form contract **Semantic Contract:** UI is an authorized projection of the same model and submits Commands; it has no business-state store. **Implementation Contract:** implement only a server-rendered shell, login/logout, Business selector, Type-scoped object list, object detail, declared operation form, Command status and known-object revision/transition/provenance inspection. A View definition declares its Type ID, permitted list/detail fields, declared relationship sections and declared operation IDs. A Form definition declares one registered operation, the Type/State context, input field names and their renderer types. The initial renderer allowlist is `text`, `textarea`, `number`, `date_time_utc`, `select`, `object_reference` and `read_only`; unsupported renderers or fields cause a configuration error rather than fallback HTML. The renderer obtains fields and permitted actions from authorized Type/View/Form definitions. It displays only committed values, includes expected versions and a stable generated Command ID in mutation forms, and maps submitted input only to the declared Command payload. Client-provided field names, Business IDs, operation IDs, object references and versions outside that declaration are rejected. Field/relationship denial and inaccessible objects use the same non-disclosing result as the retrieval service. The UI distinguishes validation denial, authorization denial, stale version, failed attempt, pending command and reconciliation-required status; it preserves entered input after safe rejection and never retries an unknown effect. For an existing-object target, an Operation declaration may add presentation metadata: a human `label`, `selection: existing`, and one `target_type_id`. GET may use that binding to discover candidates through the authorized object reader and the authorized View projection for the resolved User and Business. The resulting option value is only the declared target role's object UUID; the browser cannot choose the Business, Type, handler or Operation revision. A target declaration without this metadata remains a deferred target-entry contract. POST maps selector values into the existing target envelope, and `OperationInvocationService` remains the sole final target/effective-Type authorization authority. **Implementation Detail:** templates, CSS, AJAX implementation and presentation DTOs may follow the existing visual baseline while retaining server-rendered form fallback and keyboard/accessible-label requirements. **Deferred/Later:** visual view builder, arbitrary renderer plug-ins, portal views, dashboards, autocomplete/global search and rich-content editing. --- # 17. Bootstrap / Genesis **Semantic Contract:** foundation-only genesis establishes the minimum generic storage, Type-of-Type and foundational vocabulary required to open the platform; it does not establish human identity, Business or authority state. **Implementation Contract:** genesis runs only through a target CLI command against an empty database whose migration ledger matches the target release. It loads one immutable, versioned manifest with a digest and stable UUIDv4 seed addresses. The only permitted bootstrap exception is that the root `Type` definition may reference itself as `type_id` before ordinary Type validation exists. All other seed objects use the root Type or another seed Type declared in the same manifest. Object self-references have no database FKs; the genesis validator resolves every reference from the complete manifest before commit. Inside one coordination-locked transaction Genesis inserts only current object rows and matching revisions for the root Type, foundational Types and required foundation occurrence/ledger vocabulary, validates references and writes technical installation provenance. It creates no human User, credential, Business, Membership, Business AuthorityGrant, Business Policy, owner, superuser, permanent administrator, customer View or human runtime actor. Failure rolls back all foundation rows and leaves no usable partial store. Re-run succeeds only when the manifest digest and every stable identity match exactly; a mismatched, populated or foreign store is refused. After foundation Genesis, a separate deterministic platform opening/release installs the approved identity-lifecycle and platform `business.create` configuration using technical release provenance only. Normal runtime then follows `registration -> confirmation -> authentication -> bounded onboarding -> business.create`; every customer creation or configuration change uses Command -> validation -> authority/policy -> commit. Spearmint is created later through ordinary `business.create`, not through an implicit cross-Business bootstrap grant. ### 17.1 Normal Business creation after Genesis **Existing architectural rule:** Genesis establishes only the initial Idiosyncrasy foundation. It is not a continuing privilege bypass. After Genesis, normal Business creation and configuration use the governed runtime. **Newly resolved governance decision:** Normal Business creation is the platform-scoped `business.create` capability. It is not external provisioning, a generic `object.create` alias or Business-scoped administration because the target Business does not yet exist. An authenticated User must be authorized by the platform-level authority for this capability before an active Business context can exist. The `business.create` operation creates, in one governed atomic bootstrap transaction: - one active Business object and its initial revision; - exactly one active Business-scoped Membership for the initiating User, with descriptive kind `business_administrator`; - explicit AuthorityGrant object(s) for that Membership and Business, with the minimum operation and target-Type scope required for initial Business and governance administration; and - at least one explicit active Business-scoped Policy required before ordinary Business-scoped administration is usable. The Membership kind is descriptive and does not create permanent ownership, an immutable administrator, a fixed hierarchy or an unrestricted superuser. AuthorityGrant and Policy remain independent governed objects. Relationships do not grant authority, and missing or conflicting Policy resolution fails closed. Genesis-only `bootstrap_operator` and `platform.inspect_foundation` values are not reused for normal Business creation. **Implementation/configuration dependencies:** the approved platform-level authority source; the exact Operation Contract revision and trusted handler registration for `business.create`; the concrete initial AuthorityGrant operation/target-Type inventory; the concrete initial Policy configuration and rule inventory; and any Business-creation Event name not already fixed by the Event contract. User registration and confirmation have separate implemented Operation identities at revision `1` with trusted handlers `platform.principal-register` and `platform.principal-confirm` (legacy identifiers for User registration and confirmation); those admission dependencies are resolved and are not future work. The remaining Business-creation dependencies must be resolved without weakening the identity, isolation, authority or evidence rules above. The server resolves the initiating User and generates the Business identity; client authority claims are rejected. The Command must retain the exact Operation identity/revision and use the existing Command identity, fingerprint and duplicate-delivery semantics. Business, Membership, AuthorityGrant, Policy, provenance and required history/evidence commit coherently or the operation leaves no usable partially governed Business. Required evidence identifies the initiating User, Business and governance revisions together with Command, Action Execution, Attempt, Outcome, Provenance and the applicable Business-creation Event/causal links. **Implementation Detail:** protected-prompt library, manifest file format and root-Type field names are local choices, provided the manifest remains deterministic and auditable. **Deferred/Later:** seed-manifest merging, import bootstrap, interactive superuser installation and an ongoing universal administrator flag. --- # 18. Spearmint Design Demonstrator Spearmint is the first demonstrator, not a bespoke application. ## 18.1 Business configuration Represent Spearmint as a Business with: - authorised operator user(s) - reviewer user(s) - explicit memberships - scoped grants - Person/Organisation references - Enquiry type - Qualification type - Project type - relevant typed Relationships - versioned Policies - Workflow definition - model-driven Views No Spearmint-specific database foundation. No Spearmint-only engine. **Implementation Contract:** after runtime User admission and governed `business.create`, install a trusted, versioned, reusable Business-configuration release through the generic configuration Commands. The first product-owned configuration may define the bounded vocabulary and process for the resulting Spearmint Design Business, including `Person`, `Organisation`, `Enquiry`, `Qualification`, `Project`, `Decision`, `WorkflowDefinition`, `WorkflowExecution`, `Event`, `StateTransition`, `Policy`, `ViewDefinition` and required Business-owned relationship types. It must not contain a fixed Business or User identity, create the installing User, create Membership/AuthorityGrant prerequisites, or provision operational records. Reviewer Users, if later needed, must already exist under separate governed runtime operations and be referenced rather than provisioned by IDY-008; workflows have no identity of their own and operate under authority delegated by a User (see [delegated authority for automation](../architecture/identity-and-governance.md#delegated-authority-for-automation)). ## 18.2 First bounded process The approved first executable slice is: ```text Enquiry ↓ Qualification ↓ Project / Scoping ``` The larger lifecycle remains: ```text Enquiry → Qualification → Project/Scoping → Proposal → Internal Delivery Authorisation → Design → Design Acceptance → Development → Review → Final Acceptance → Launch → Handover → Completion ``` The three approval concepts must remain distinct; do not collapse them into a generic `approved` field. ## 18.3 Enquiry Minimum configuration: - source - contact reference or explicit unmatched status - summary - received time - provenance Creation occurs through Command. No public intake connector is required initially. **Implementation Contract:** `Enquiry` requires `source`, `summary`, `received_at` (UTC) and exactly one of an authorized Person/Organisation contact reference or `contact_unmatched = true`. Its declared States are `received`, `qualification_submitted`, `rejected` and `scoped`. An operator with `create_enquiry` creates it in `received`; the resulting local commit records provenance and one `enquiry.created` Event. The Event starts at most one execution of the active Spearmint workflow revision through the `workflow_trigger_keys` uniqueness constraint. ## 18.4 Qualification An operator records: - requirements - fit assessment An authorised reviewer records a scoped Decision. Progression is blocked when: - required evidence is missing - applicable Policy conflicts - authority is absent Rejection remains historical. **Implementation Contract:** `Qualification` requires its Enquiry reference, requirements, fit assessment, submitter User and submitted time. Its States are `submitted`, `approved` and `rejected`. Submission is a declared operator Command that creates the Qualification, relates it to the Enquiry, transitions the Enquiry to `qualification_submitted` and records `qualification.submitted`. The workflow waits for that Event, creates an approval request and waits for an authorized Decision. The Qualification Policy permits a reviewer to create an `approved` or `rejected` Decision only when the exact Qualification and Enquiry revisions, applicable Policy revision and requirements are current, and the reviewer User differs from the recorded submitter. The Decision records its target versions, reviewer, determination, rationale and Policy revision; its commit transitions Qualification to `approved` or `rejected` and records `qualification.decided`. A rejected Decision transitions the Enquiry to `rejected` and ends the workflow. Missing evidence, conflict, stale inputs or absent authority leaves no progression effect. ## 18.5 Project / Scoping A governed Action creates Project and source/customer relationships only after the applicable positive qualification Decision. Required inputs: - scope summary - assigned responsible user Record coherently: - transition - Command - Attempt - outcome - resulting objects/relationships Duplicate delivery must not create another Project. **Implementation Contract:** `Project` requires `scope_summary`, exactly one assigned responsible User and State `scoping`. The positive-decision continuation issues a local `create_project_from_qualification` Command. In one transaction it rechecks the exact positive Decision, all referenced revisions, reviewer authority, active Policy and Qualification state; creates the Project; relates Project to the Qualification and originating Enquiry; relates its responsible User; transitions Enquiry to `scoped`; records required provenance, Event and transitions; and reserves the `Qualification -> Project` active relationship slot. The slot allows at most one active Project for each Qualification. A later distinct Command that reaches the same Qualification gets a cardinality conflict; it must not create another active Project. Initial relationship cardinalities are: Enquiry-to-Qualification `0..1` active, Qualification-to-Project `0..1` active, Project-to-originating-Enquiry exactly `1`, Project-to-Qualification exactly `1`, and Project-to-responsible-User exactly `1`. Enquiry-to-Person and Enquiry-to-Organisation are each `0..1`, subject to the explicit unmatched-contact representation. The pinned workflow is `on enquiry.created -> wait_for qualification.submitted -> request approval -> wait_for qualification.decided -> condition Decision.approved -> local create_project_from_qualification -> end`; its false/rejected continuation ends with recorded rejection. It uses no external integration, AI action or automatic retry of a settled failure. **Deferred/Later:** public form intake, customer matching, proposals, delivery authorization, design/review/launch stages, communication and live external effects. --- # 19. First Executable Milestone The first true milestone is **not** “a nice dashboard”. It is: > A user can authenticate into Idiosyncrasy, enter an authorised Business context, inspect addressable objects, and perform a governed state-changing operation through Command → Validation → Authority/Policy → Commit, with resulting state change and provenance/history addressable. Acceptance requires inspectable: - Command - Action Execution - Attempt - changed object revision - state-transition occurrence - source/actor/authority references And proves: - unauthorized requests fail - stale requests fail - duplicate requests do not bypass Command identity - unknown outcomes remain explicit - UI/API/Workflow/AI all use the same mutation path --- # 20. Development and Testing Strategy ## 20.1 Test stack **Semantic Contract:** verification must prove the architecture's isolation, durability and recovery invariants rather than merely PHP syntax. **Implementation Contract:** the foundation stage installs the pinned verified PHPUnit 11 PHAR and `tests/bootstrap.php` described in section 6. The suite reads an explicitly configured, isolated MariaDB database name that must match an `IDY_TEST_` prefix; it refuses any other database. Each test case creates unique fixture IDs and rolls them back or truncates only that isolated database. Concurrency tests open two independent PDO connections. Fault injection is exposed only through test-only persistence/adapter seams, never HTTP parameters or production privilege bypasses. The runner executes migrations from an empty test database before the integration suite, verifies `schema_migrations` checksums, and reports the PHP version, MariaDB version and exact PHAR hash. The required commands are: ```text php bin/runtime-migrate.php --database=test php tools/phpunit-11.phar --bootstrap tests/bootstrap.php tests ``` The current implementation specification selects: - PHPUnit 11 - PHP 8.3.33 - isolated MariaDB 10.5.26/InnoDB fixtures - two independent DB connections for concurrency tests - fault injection at repository/transaction/adapter boundaries Do not use SQLite as evidence of InnoDB transaction/concurrency correctness. **Implementation Detail:** test helper classes, fixture factories and test directory grouping are local choices. **Deferred/Later:** browser-driver selection and a production-like load suite are not prerequisites for the first runtime. Manual keyboard/mobile checks remain release evidence until a browser suite is deliberately introduced. ## 20.2 Required test categories ### Unit - type validation - typed value validation - State validation - Policy expression evaluation - permission decisions - command canonicalization - fingerprint generation - workflow transition rules - timezone validation ### Persistence/integration - object creation - revision creation - relationship integrity - transaction rollback - historical references - command deduplication - retrieval authorization ### Concurrency - same expected version submitted twice - concurrent grant/revocation versus commit - duplicate Command delivery - expired workflow lease - commit acknowledgement loss ### Security - authentication failures - CSRF - session fixation - rate limiting - cross-Business access - inaccessible-object disclosure - unauthorized relationship access - unauthorized file access - malicious upload - unsafe markup ### Workflow - conditions - action failure - approval - wait/resume - cancellation - restart - lease expiry - unknown external effect - reconciliation - step limit ### Acceptance - first executable milestone - Spearmint enquiry - qualification decision - project creation - duplicate prevention - new type creation without new PHP/domain table - no-AI operation --- # 21. Architecture Conformance Gates The following gates are mandatory evidence, not documentation claims: 1. **Universal representation** — representative objects across business data, types, relationships, configuration, knowledge, workflows/nodes, events, views, permissions and integrations use the same primitive. 2. **Type/relationship integrity** — invalid values, missing endpoints and unauthorized changes fail. 3. **Cross-capability reuse** — the same object participates in multiple capabilities without parallel domain stores. 4. **Human operation/no AI** — core operations work with no provider and with provider failure. 5. **Structured retrieval** — deterministic type/relationship/state/time/permission constraints work before optional semantic retrieval. 6. **Knowledge** — sources, authority and provenance survive retrieval and change. 7. **Isolation** — cross-Business reads/writes/relationships/files/search/integration operations fail safely. 8. **History/explanation** — actions can be traced to actor, definitions, evidence and outcome. 9. **Execution** — stale changes, duplicates, retries, waits and cancellation obey the execution contract. 10. **Generated presentation** — views/forms render from definitions and remain authorized. 11. **Controlled AI** — AI output is schema-valid, authorized and approved where required. 12. **Evolution** — observation, suggestion, review, implementation and measurement remain distinct. --- # 22. Security and Operations ## 22.1 Secrets Keep credentials, encryption keys, provider tokens and deployment credentials outside source control and public web bundles. The existing documentation identifies PHP external configuration as an established hosting-compatible pattern. The new runtime must not expose secrets through markup, logs, exceptions or AI prompts. ## 22.2 Files Files use opaque handles and live outside the public web root where authorization is required. Initial upload controls must include: - size checks - server-detected type - safe storage names - path traversal protection - lifecycle cleanup - authorization on reads/replacements/deletion - malicious SVG/polyglot/malformed-file tests ## 22.3 Deployment ### Current release-foundation status The current release boundary is reviewed in [release/target-release.json](../../release/target-release.json) and resolves to 131 source files. The deterministic manifest, [target check](../../bin/target-check.ps1), provenance-bound package builder and [operator release command](../../bin/target-release.ps1) are implemented and locally checked. The guarded [target-local launcher](../../bin/target-local.ps1) is limited to loopback database configuration and an isolated local session directory; production release source is an exact GitHub commit, not the arbitrary local working tree. The historical `release-staging/` snapshot has been retired and is no longer part of release verification. The operator command reports seven phases: local preflight, package creation/verification, production connection, staging/upload, remote verification, blocked activation and final result. It implements local packaging and remote staging/verification only. It transfers the exact locally verified package contents with one recursive SCP operation, then verifies the remote manifest, two control files, file list, byte counts and hashes. Remote verification invokes `sh`, `-s` and `--` as separate SSH arguments while the read-only verification script is supplied through stdin; this preserves the Windows PowerShell/OpenSSH argument boundary and avoids corrupting the shell's `set` command. Native SSH/SCP failures retain executable, non-secret context, exit code, output and PowerShell exception diagnostics without printing arguments or password material. Progress output does not alter deployment semantics. It supports configured SSH keys and an operator-supplied native interactive SSH password fallback without persisting password material; strict host-key verification remains mandatory. Activation remains pending because no safe atomic switch or rollback mechanism is established for the documented Plesk/SSH layout. Normal releases remain code/assets only; provisioning, migration, Genesis, platform opening, database mutation and Plesk changes are not performed. Verify before release: - PHP 8.3.33 availability - required PHP extensions - MariaDB 10.5.26/InnoDB - TLS - PHP-FPM environment/configuration - web-root exclusions - file permissions - database least privilege - backup and restore - key custody - health checks - sanitized logs - error correlation On Plesk/Apache, verify directory-index precedence and relevant PHP/Authorization-header behaviour rather than assuming the host configuration. **Implementation Contract:** a release contains one target public directory pointing to the target front controller, one non-public configuration location, one target database credential and the same application release for CLI dispatch. The migration command is `php bin/runtime-migrate.php`; it obtains the migration lock and refuses a checksum mismatch. A deployment applies migrations before enabling the release, runs the PHAR test suite against its isolated fixture database, verifies a target health command that checks configuration, PDO with `pdo_mysql` and migration state without exposing secrets, then enables the target entry point. The dispatcher runs `php bin/runtime-dispatch.php --once` from cron at least once per minute as a distinct technical executor recorded as execution provenance only (no independent authority; it operates under authority delegated by a User) when that worker is implemented; the current repository does not yet contain `bin/runtime-dispatch.php`. Rollback is release-code rollback only when the applied migrations remain forward-compatible; otherwise release remains disabled and a documented forward repair migration is required. Production target deployment never shares credentials, sessions, routes or database with the optional legacy deployment. The implemented staging path is explicit: `php bin/provision-target.php --database=staging` requires `IDY_STAGING_DB_NAME` to match `IDY_TARGET_DB_NAME` and rejects the fixed production identity `idio2plat` and production-looking names. The staging operator bundle is internal-only and is not published or consumed by the GitHub deployment workflow. The real Plesk staging filesystem, PHP-FPM environment and staging database remain deployment prerequisites rather than repository evidence. ## 22.4 Recovery Backups must account for encryption key custody. Record: - backup retention - restoration authorization - restore procedure - recovery test evidence - operational ownership --- # 23. How Luna Must Use This Plan This document is intended to **begin the build**, not merely describe it. The build is deliberately staged. Luna must never be instructed to implement the whole document in one pass. ## 23.1 Stage discipline For every stage: 1. Read the relevant current Idiosyncrasy documentation. 2. Read only the applicable section of this plan, especially the stage objectives, dependencies and exit criteria. 3. Inspect the repository before changing anything. 4. State the exact files/modules that will be changed. 5. Implement only the bounded stage/task. 6. Add or update focused tests. 7. Run the relevant test suite and static/lint checks available in the repository. 8. Inspect the resulting diff for architectural drift. 9. Report: - files changed; - database migrations added; - tests added/changed; - commands/checks run and their results; - unresolved issues; - whether the stage exit criteria are satisfied. 10. Stop at the stage boundary unless the next task is explicitly requested. A stage is not complete because code exists. It is complete only when its exit criteria and tests are satisfied. ## 23.2 No silent architecture decisions Luna may choose ordinary implementation details inside an already specified boundary. Luna must stop and report if it encounters a decision that changes: - the universal object semantics; - object/type/version semantics; - relationship semantics; - authority or tenant isolation; - Command admission/commit semantics; - workflow execution guarantees; - configuration/versioning semantics; - AI execution authority; - durable audit/history semantics; - the physical persistence strategy materially enough to affect the semantic contract. Do not solve these by adding an ad-hoc abstraction merely to keep coding. ## 23.3 Stage gates The following are hard gates: **Gate A — Runtime foundation:** native autoloading, target configuration/PDO, migration ledger and no-Composer test bootstrap work only against isolated target/test databases. **Gate B — Controlled genesis:** the root Type and minimum generic foundation vocabulary can be seeded atomically, repeatedly and without persistent human identity, Business or authority state. **Gate C — Normal access:** authentication, current membership/grant/Policy checks and constrained authorized inspection are proven before normal Business data is exposed. **Gate D — Governed mutation:** every consequential normal mutation writes Command, Attempt, Outcome, revision, provenance and required Event/transition records coherently before relationships, UI actions or workflows depend on it. **Gate E — Graph and UI:** relationship authorization/cardinality and model-projection forms are proven before Spearmint configuration is operated by a user. **Gate F — Workflow:** one committed Event starts at most one persisted execution; lease/restart, approval, waiting, cancellation and local-action recovery are proven before the first business process is accepted. **Gate G — Demonstrator:** Spearmint Enquiry -> Qualification -> Project/Scoping passes happy and hostile fixtures without bespoke schema/code. ## 23.4 What Luna should build first The first request is **IDY-001 only**. Do not start by creating the CRM, dashboard, workflow engine or Spearmint screens. The first objective is to establish a trustworthy runtime foundation. Once that is proven, proceed one bounded task at a time. --- # 24. Corrected Implementation Stages ## 24.1 Executable dependency order This is the only executable implementation order. It supersedes the v2.0 phase/backlog inventory retained later for traceability. ```text Bootstrap foundation ↓ Foundational definitions and controlled genesis ↓ Normal identity, Business context and constrained authorised inspection ↓ Governed Command mutation with history and provenance ↓ Relationships and model-projection UI ↓ Bounded workflow and dispatcher ↓ Spearmint configuration and demonstrator acceptance ``` | Stage | Bounded implementation contract | Exit evidence | |---|---|---| | `IDY-001` Repository isolation audit | Classify legacy routes/schema as legacy only; select target public entry point, database/config namespace and session cookie. | A reviewed target/legacy route and database isolation matrix. | | `IDY-002` Runtime foundation | First-party autoloader, composition root, PDO/configuration, target request boundary, migration runner/ledger, verified PHPUnit PHAR and safe test bootstrap. | Target boots; migrations and PHAR tests run only against an `IDY_TEST_` database; no Composer dependency or instruction. | | `IDY-003` Generic store and genesis | Universal object/revision tables and first-slice support tables; Type validator root; controlled genesis manifest/CLI. | Matching genesis is idempotent; mismatched/partial stores fail; credentials remain outside generic retrieval. | | `IDY-004` Normal access and inspection | Password session, rate limit and CSRF controls; membership/grant/Policy evaluation; known-object and Type-scoped authorized inspection. | Login reaches only authorized Businesses; cross-Business/non-disclosure probes pass. | | `IDY-005` Governed mutation/history | Command/Action Execution/Attempt/Outcome, expected versions, provenance, Event/transition records, shared command endpoint and reconciliation. | One declared local operation proves denied, stale, duplicate, failure, unknown and coherent-history behavior. | | `IDY-006` Graph and generic UI | Relationship Types/objects/index/slots, authorized traversal, View/Form definitions and server-rendered generic projection. | A human completes declared work without direct SQL; UI cannot bypass Commands or disclose denied fields. | | `IDY-007` Bounded workflow | Event trigger admission, sequential interpreter, wait/approval/local-command nodes, durable dispatcher and lease/recovery behavior. | One Event admits one execution; lease/restart/cancellation tests preserve Command and Attempt identity. | | `IDY-008` Business configuration | Install an approved reusable versioned configuration release against an existing Business through target configuration Commands only. Spearmint is the first runtime Business use case, created separately through `business.create`. | No Spearmint table, controller or engine exists; reusable Type/Policy/Workflow/View declarations validate without provisioning identity, authority or operational data. | | `IDY-009` Demonstrator acceptance | Run Enquiry -> Qualification -> Project/Scoping with happy, denied, stale, rejected, duplicate and no-AI fixtures. | First-milestone automated and required manual evidence passes. | | `IDY-010` Surface UI | Provide a thin, usable Business-facing projection over the established foundation and a feedback loop for product learning. Reuse or adapt existing UI material where it conforms; all mutations use the governed Command path. | **Bounded demonstrator/read-result surface implemented and HTTP-verified:** the existing authenticated server-rendered shell, server-governed Business context, persisted Presentation Object graph, generic `RenderablePresentation.elements` projection and `AuthorizedObjectReader` provide the Enquiry -> Qualification read/result loop; configured Operations project declared inputs and existing authorized targets into a generic HTML form with readable labels, while continuing through `OperationInvocationService` and `CommandHandler` with AuthorityGrant/Policy and expected-version protection. IDY-010 implementation is closed at this bounded scope. The canonical dedicated `idy010` artifact records **69/69 HTTP acceptance — PASS** on 2026-09-19 with zero failures, zero runtime diagnostics and clean shutdown. The earlier **42/42** run is historical/superseded and **67/67** is an intermediate BUILD report. The Surface is intentionally not a finished/full product UI; the full configured PHPUnit result remains **UNKNOWN — the full configured PHPUnit run was previously stopped before producing a final summary.**, and broader capabilities remain future/refinement work rather than unresolved IDY-010 implementation defects. | An implementation task changes only one stage or a named exit-evidence gap. It identifies canonical owner, allowed files, required contract, focused tests, exact checks and remaining limits; it stops at the stage boundary. A task that discovers a contradiction in a settled semantic contract stops for owner review. Routine local choices remain implementation details. ## 24.5 IDY-010 and Provisional Future Scope IDY-010 follows the dependency chain `Foundation-only Genesis -> Platform Opening -> User Registration -> Confirmation -> Authentication -> Bounded Onboarding -> business.create -> IDY-008 -> IDY-009`. It introduces no replacement identity, Business, Genesis, Command, workflow or IDY-009 contract. Its purpose is to make the existing foundation usable enough to learn from real Business interaction. IDY-011 onward are provisional future stages whose scope, ordering, boundaries and detailed architecture remain subject to exploration. Do not derive implementation contracts, acceptance criteria, Operation identifiers, schemas, migrations, test requirements or module boundaries for those stages from this plan. Future stages may be split, combined, renamed or reordered as IDY-010 use produces evidence. The provisional capability domains are recorded in the [capability catalogue](../product/capabilities.md#provisional-future-capability-business-configuration-domains). They are not a stage list or a fixed module catalogue. The final balance between generic/model-driven and purpose-built UI, the configuration of Business DNA, and the use of optional AI-assisted interaction remain open questions for later PLAN/BUILD cycles. ## 24.2 First executable milestone acceptance The milestone is satisfied only when an authorized human can authenticate, select an authorized Business, list and inspect permitted addressable objects, and complete one declared mutation through the shared Command pipeline. The resulting object revision, Command, Action Execution, Attempt, Outcome, provenance, Event and any State-transition occurrence are inspectable subject to authority. Required automated fixtures prove: denied and cross-Business access disclose no protected data; stale versions change nothing; duplicate Command delivery makes one semantic effect; a failed required-history write rolls back the effect; a repeated Enquiry Event starts one workflow execution per active workflow revision; an expired dispatcher lease does not duplicate a local action; a rejected Qualification never creates a Project; and distinct Commands cannot create two active Projects for one approved Qualification. Required release evidence proves the no-AI path, migration/health checks, keyboard operation and mobile layout of the first UI. **Deferred/Later:** the broader eleven MVP criteria remain product acceptance beyond this first executable milestone unless a later stage explicitly enables them. ## 24.3 Historical v2.0 planning inventory The remaining phase, backlog, completion and summary material was retained to preserve prior planning identifiers and scope history. It is non-normative and must not be used to derive dependencies, toolchain choices or implementation work. Any old `IDY-011` or later labels in this retained inventory are historical identifiers only, not current future stages or commitments. Section 24.1 controls all build order and stage acceptance; the provisional IDY-010+ boundary above controls current future planning. ## Phase 0 — Repository and Runtime Foundation ### Objectives - establish native first-party autoloading - establish PSR-4 - establish `App\Runtime` - establish composition root - establish configuration boundary - establish PDO factory - establish error handling - establish request/response abstractions - establish migration mechanism - establish PHPUnit - establish baseline security headers ### Exit criteria - application boots cleanly - database connection works against a dedicated database - native autoloader works - PHPUnit runs - no legacy controller writes into the new runtime --- ## Phase 1 — Authentication and Business Context Build: - User (legacy Type name Principal) - credential storage - login/logout - session lifecycle - CSRF - Business object - membership - AuthorityGrant - Business selection - scoped context resolver ### Exit criteria A user can log in and select only a Business to which they have membership/authority. --- ## Phase 2 — Object Persistence and Type System Build: - `objects` - `object_revisions` - Type objects - Type revision handling - typed-value validator - object repository - object read service - object mutation through Command only - version checking ### Exit criteria A valid typed object can be created, read and revised through the authoritative pipeline. --- ## Phase 3 — Command Pipeline Build: - Command identity - canonicalization - SHA-256 request fingerprint - `command_keys` - Action Execution - Attempt - provenance - commit transaction - duplicate handling - stale handling - Unknown/Reconciliation status - HTTP `/commands` ### Exit criteria All consequential changes have one mutation path. --- ## Phase 4 — State and History Build: - State definitions - current State references - transition occurrences - historical revisions - provenance - effective/recorded time ### Exit criteria A state transition is independently inspectable and historically meaningful. --- ## Phase 5 — Relationships and Business Graph Build: - Relationship Type - Relationship objects - relationship validation - cardinality - endpoint constraints - `relationship_index` - relationship navigation - relationship authorization ### Exit criteria A shared Person/Organisation/Business object can participate in typed relationships without duplicate capability-owned records. --- ## Phase 6 — Policy and Authority Evaluation Build: - Policy objects - allowlisted expression interpreter - policy composition - scoped Decision - conflict handling - exception/delegation representation - commit-time policy recheck ### Exit criteria A valid object operation can still be refused because the actor lacks applicable authority or Policy permission, and a relationship cannot create authority. --- ## Phase 7 — Model-Driven UI Foundation Build: - application shell - login - Business selection - navigation - object list - object detail - view definitions - allowlisted field renderers - operation forms - Command status - revision/history views - small JS enhancements ### Exit criteria An authorized human can operate the first runtime without direct database access. --- ## Phase 8 — Foundation Genesis and Platform Opening Build: - versioned foundation manifest - CLI initializer with technical installation provenance - Type-of-Type and minimum foundational Type definitions - Genesis occurrence/ledger evidence - fresh-store refusal and idempotent re-run detection - separate deterministic platform opening/release for identity Operations, trusted handlers, onboarding rules, platform `business.create` and active platform Policy The opening sequence then continues with User registration, confirmation/onboarding and authentication/authorization integration before ordinary `business.create`. No phase creates a Genesis User or Genesis Business. ### Exit criteria A fresh isolated database can be initialized safely and deterministically. --- ## Phase 9 — Workflow Runtime Build: - Workflow Definition - Workflow revision pinning - Workflow Execution - nodes/transitions - local Actions - Conditions - approvals - waits - execution lease - CLI dispatcher - resume/reconciliation - 100-step safety bound ### Exit criteria A deterministic workflow can run without AI and survive restart/recovery. --- ## Phase 10 — Spearmint Configuration Build Spearmint configuration using the runtime only: - Business - Persons/Organisations - Enquiry - Qualification - Project - relationships - Policies - Views - Workflow ### Exit criteria No Spearmint-specific database table or engine is required. --- ## Phase 11 — Spearmint Demonstrator Implement: ```text Enquiry → Qualification → Project/Scoping ``` Prove: - provenance - reviewer Decision - authority - Policy - state transitions - Project creation - relationship creation - duplicate prevention - history - UI operation ### Exit criteria First executable milestone passes. --- ## Phase 12 — Knowledge and Structured Retrieval Build: - Knowledge objects - source references - provenance - applicability - structured retrieval - permission-aware context assembly - manual knowledge capture ### Exit criteria A human can retrieve applicable knowledge without AI, with source and authority intact. --- ## Phase 13 — Content and Communication Foundations Build only the smallest reusable capability required by a demonstrator. Potentially: - content objects - templates - notifications - email abstraction - communication history No broad connector catalogue. --- ## Phase 14 — External Integrations Add bounded adapters only after the internal model is stable. Each adapter must: - translate into/from platform concepts - use Command/Action/Attempt semantics - preserve external failure states - avoid provider-specific business models - support explicit capabilities rather than a mandatory universal provider interface Start with fake adapters for boundary tests. --- ## Phase 15 — Analytics and Evolution Build deterministic observation first: ```text Observe ↓ Understand ↓ Suggest ↓ Approve ↓ Implement ↓ Measure ``` A suggestion must remain distinct from an implemented change. AI can later assist analysis, but the evolution mechanism must remain understandable without AI. --- ## Phase 16 — Optional AI Boundary Only after deterministic operation works. AI adapters may provide: - natural-language interaction - content generation - analysis - recommendations - configuration assistance - knowledge retrieval assistance - workflow assistance AI output must enter the normal validation/authority/approval path. No AI provider becomes a foundational runtime dependency. --- # Historical v2.0 Dependency-Ordered Build Backlog The following is the implementation sequence. Each item should be treated as a small, bounded engineering task rather than a request to build an entire phase in one pass. | ID | Task | Depends on | |---|---|---| | IDY-001 | Repository audit against this plan | — | | IDY-002 | Establish No Composer; native autoloading / PSR-4-style namespaces | IDY-001 | | IDY-003 | Create `App\\Runtime` composition root | IDY-002 | | IDY-004 | Establish runtime configuration boundary | IDY-003 | | IDY-005 | Establish PDO + `pdo_mysql` connection factory | IDY-004 | | IDY-006 | Establish migration mechanism | IDY-005 | | IDY-007 | Establish PHPUnit 11 | IDY-002 | | IDY-008 | Establish HTTP/request/response boundary | IDY-003 | | IDY-010 | User/credentials persistence (legacy Type name Principal) | IDY-006 | | IDY-011 | Login/logout/session lifecycle | IDY-010 | | IDY-012 | CSRF/rate limiting/security middleware | IDY-011 | | IDY-013 | Business object foundation | IDY-006 | | IDY-014 | Membership object | IDY-013 | | IDY-015 | AuthorityGrant object | IDY-014 | | IDY-016 | Business context resolver | IDY-015 | | IDY-017 | Authentication/Business isolation tests | IDY-016 | | IDY-020 | `objects` table | IDY-006 | | IDY-021 | `object_revisions` table | IDY-020 | | IDY-022 | Object repository | IDY-021 | | IDY-023 | Type definition representation | IDY-020 | | IDY-024 | Type revision representation | IDY-023 | | IDY-025 | Typed value validator | IDY-024 | | IDY-026 | Object retrieval service | IDY-022, IDY-025 | | IDY-027 | Expected-version mutation primitive | IDY-022 | | IDY-028 | Object revision/history tests | IDY-027 | | IDY-030 | Command canonicalization | IDY-027 | | IDY-031 | Command fingerprinting | IDY-030 | | IDY-032 | `command_keys` | IDY-031 | | IDY-033 | Command/Action/Attempt objects | IDY-032 | | IDY-034 | Command admission transaction | IDY-033 | | IDY-035 | Command commit transaction | IDY-034 | | IDY-036 | Duplicate/stale/unknown handling | IDY-035 | | IDY-037 | `/commands` endpoint | IDY-036 | | IDY-038 | Command concurrency tests | IDY-037 | | IDY-040 | State definitions | IDY-025 | | IDY-041 | State transitions | IDY-040 | | IDY-042 | Transition occurrence/history | IDY-041 | | IDY-043 | Effective/recorded time support | IDY-042 | | IDY-045 | History conformance tests | IDY-043 | | IDY-050 | Relationship Type | IDY-024 | | IDY-051 | Relationship object | IDY-050 | | IDY-052 | Relationship validator | IDY-051 | | IDY-053 | Relationship index | IDY-052 | | IDY-054 | Relationship navigation | IDY-053 | | IDY-055 | Relationship authorization | IDY-054, IDY-015 | | IDY-056 | Graph/isolation tests | IDY-055 | | IDY-060 | Policy object | IDY-024 | | IDY-061 | Allowlisted policy expression evaluator | IDY-060 | | IDY-062 | Policy composition | IDY-061 | | IDY-063 | Decision object/review | IDY-062 | | IDY-064 | Commit-time authority/policy recheck | IDY-063, IDY-035 | | IDY-065 | Policy conflict tests | IDY-064 | | IDY-070 | View Definition | IDY-024 | | IDY-071 | Renderer registry | IDY-070 | | IDY-072 | Application shell | IDY-071, IDY-016 | | IDY-073 | Login UI | IDY-072 | | IDY-074 | Business selector | IDY-073 | | IDY-075 | Object list/detail | IDY-074, IDY-026 | | IDY-076 | Operation forms | IDY-075, IDY-037 | | IDY-077 | Command status UI | IDY-076 | | IDY-078 | History/provenance UI | IDY-077 | | IDY-080 | Genesis manifest format | IDY-064, IDY-070 | | IDY-081 | Bootstrap CLI | IDY-080 | | IDY-082 | Idiosyncrasy seed data | IDY-081 | | IDY-083 | Genesis idempotency/conflict handling | IDY-082 | | IDY-085 | Workflow Definition representation | IDY-024 | | IDY-086 | Workflow Execution representation | IDY-085 | | IDY-087 | Sequential interpreter | IDY-086 | | IDY-088 | Condition node | IDY-087, IDY-061 | | IDY-089 | Local mutation Action | IDY-087, IDY-037 | | IDY-090 | Approval node | IDY-089, IDY-063 | | IDY-091 | Wait node | IDY-090 | | IDY-092 | Dispatcher/lease | IDY-091 | | IDY-093 | Resume/reconciliation | IDY-092 | | IDY-094 | Workflow execution tests | IDY-093 | | IDY-100 | Spearmint Business configuration | IDY-083, IDY-056 | | IDY-101 | Enquiry type/configuration | IDY-100 | | IDY-102 | Qualification type/Decision Policy | IDY-101 | | IDY-103 | Project/relationship configuration | IDY-102 | | IDY-104 | Spearmint bounded workflow | IDY-103, IDY-094 | | IDY-105 | Spearmint UI views/forms | IDY-104, IDY-078 | | IDY-106 | Demonstrator acceptance suite | IDY-105 | | IDY-110 | Structured retrieval service | IDY-056, IDY-026 | | IDY-111 | Permission-aware retrieval | IDY-110, IDY-064 | | IDY-112 | Knowledge/source objects | IDY-111 | | IDY-113 | Knowledge applicability | IDY-112 | | IDY-114 | Knowledge retrieval tests | IDY-113 | | IDY-120 | Content foundation | IDY-070 | | IDY-121 | Communication foundation | IDY-037, IDY-120 | | IDY-122 | Fake external adapter | IDY-121 | | IDY-123 | Adapter attempt/outcome handling | IDY-122 | | IDY-130 | Analytics observations | IDY-106 | | IDY-131 | Suggestion object/evidence | IDY-130 | | IDY-132 | Review/approval of suggestion | IDY-131 | | IDY-133 | Measurement outcome | IDY-132 | | IDY-140 | AI provider abstraction | IDY-114 | | IDY-141 | AI proposal validation | IDY-140 | | IDY-142 | AI authority/approval boundary | IDY-141 | | IDY-143 | AI-disabled conformance suite | IDY-142 | The IDs are planning identifiers, not new architecture decision numbers. --- # 25. Reference Acceptance Inventory (Status Owns Evidence) The first demonstrator is complete only when all of the following are true: - [ ] Fresh dedicated MariaDB 10.5.26 database can be bootstrapped. - [ ] User can authenticate securely. - [ ] User can select an authorized Business. - [ ] Business isolation is enforced server-side. - [ ] Universal objects can be created/read/revised. - [ ] Types are first-class addressable objects. - [ ] Typed values are deterministically validated. - [ ] State definitions are distinct from transition occurrences. - [ ] Relationships are first-class where required. - [ ] Relationship validation enforces endpoint/type/cardinality rules. - [ ] Relationships do not grant authority. - [ ] Policies are versioned and deterministically evaluated. - [ ] Decisions are scoped and attributable. - [ ] All mutations use CommandHandler. - [ ] Command identity prevents duplicate semantic admission. - [ ] Stale versions are rejected. - [ ] Required state/history/provenance commits atomically. - [ ] Unknown outcomes remain explicit. - [ ] Workflow definitions are addressable and versioned. - [ ] Workflow executions pin their definition revision. - [ ] Sequential conditions/actions/approval/waits work. - [ ] Dispatcher recovery works. - [ ] Model-driven UI can operate the system. - [ ] Spearmint is represented entirely through configuration/types/relationships/policies/workflows. - [ ] Enquiry → Qualification → Project/Scoping works. - [ ] Qualification approval is explicit. - [ ] Project creation requires the governed positive decision. - [ ] Duplicate project creation is prevented. - [ ] History/provenance is inspectable. - [ ] AI can be completely absent and the demonstrator still works. - [ ] PHPUnit suite exists and runs. - [ ] MariaDB 10.5.26 concurrency tests exist. - [ ] Security/isolation tests exist. - [ ] Architecture conformance gates have evidence. --- # 26. What Must Not Be Built Yet Do not allow implementation drift into: - a conventional CRM architecture - separate tables/models for every business concept - capability-owned customer databases - microservices - Kubernetes/container orchestration without need - a general message broker - a vector database as foundational storage - autonomous AI agents - provider-dependent core functionality - arbitrary generated PHP/application code - complete connector catalogues - complete CMS publishing estate - full marketing automation suite - exhaustive analytics - accounting/ERP coverage - broad portal functionality - automatic recurrence language - live external publishing before the internal mutation/runtime is proven A feature belongs in the runtime only if it can be expressed through the approved model or introduces genuinely reusable execution behaviour under the product's composition rules. --- # 27. Engineering Rule for New Requirements Before adding code, ask: 1. Can this be represented by an existing Type? 2. If not, can it be represented by a new Type and configuration? 3. Can existing Relationships express it? 4. Can an existing Workflow/Action express the behaviour? 5. Can an existing View/Content mechanism present it? 6. Can an existing Policy express the authority rule? 7. Can an existing engine/responsibility execute it? 8. Does it genuinely require new reusable execution behaviour? 9. Does that new behaviour preserve the universal object model? 10. Does it remain useful with AI disabled? Only the final question supports a genuinely new execution responsibility. --- # 28. Copilot/Luna Task Protocol Each implementation task should contain: ```text TASK ID Objective: What single outcome must exist when this task is complete? Canonical owner: Which Idiosyncrasy document owns the meaning? Dependencies: Which prior tasks must already exist? Allowed scope: Which files/components may be changed? Required mechanism: What does the implementation architecture require? Contracts: What interfaces/data/API behaviour must remain stable? Tests: What focused evidence must be added or run? Acceptance: What observable behaviour proves completion? Definition of done: What must be true before the task is considered complete? ``` Luna/Copilot must **not** silently redesign architecture while implementing a task. If a genuine conflict with the current documentation is discovered: 1. stop the affected implementation slice; 2. identify the canonical document; 3. describe the conflict; 4. do not invent a new architecture decision number; 5. request owner review where the conflict cannot be resolved by the existing specification. Routine implementation detail does not require a new D-number. --- # 29. First Luna/Copilot Instruction The following is historical onboarding text retained for traceability. It is not an active task instruction; use the current task, canonical owners, implementation contracts, development guidance and status instead. ```text Read the relevant current Idiosyncrasy documentation and the applicable section of docs/implementation/implementation-plan.md before changing application code. Do not load this planning document in full by default. The documentation is authoritative. Treat D01-D10 as settled. Do not redesign the product into a conventional SaaS/CRM architecture. Your task is repository assessment only. Compare the current repository against the implementation plan and report: 1. what already exists and can safely be reused; 2. what is legacy and must remain outside the new runtime; 3. what implementation mechanisms are missing; 4. any direct conflicts between repository code and the current specification; 5. the smallest dependency-ordered implementation task that should be done first; 6. the tests/evidence that task requires. Do not implement anything yet. Preserve these non-negotiable properties: - universal id + type + value model; - one Business Graph; - first-class addressable Types; - explicit relationships; - explicit authority and Policy; - independent Business identity and Business-scoped isolation; - Command-centred mutation; - durable versions and history; - deterministic workflows; - explicit Unknown/Reconciliation; - model-projection UI; - AI optionality; - structured-first retrieval; - readable/editable/versionable configuration; - no arbitrary runtime code generation; - modular monolith; - PHP 8.3.33; - MariaDB 10.5.26/InnoDB; - no application framework; - no Composer; - first-party native autoloader with PSR-4-style namespaces; - Spearmint Design as the first demonstrator. Do not create new architecture decisions merely because code is missing. The implementation specification already selects the smallest conforming mechanisms. End with a proposed first implementation task using the task protocol in the implementation plan. ``` --- # 30. Superseded Build Sequence Summary (Traceability Only) ```text DOCUMENTATION ↓ Repository audit ↓ No-Composer runtime foundation ↓ Authentication + Business context ↓ Universal objects + Types ↓ Command pipeline ↓ State + History ↓ Relationships ↓ Authority + Policy ↓ Model-driven UI ↓ Controlled Genesis ↓ Workflow runtime ↓ Spearmint configuration ↓ Spearmint Enquiry ↓ Qualification ↓ Project / Scoping ↓ Architecture acceptance gates ↓ Knowledge + Retrieval ↓ Content / Communication ↓ Integrations ↓ Analytics / Evolution ↓ Optional AI ``` The first major proof is therefore not “Idiosyncrasy has lots of features”. It is: > **Spearmint Design can be represented and operated by the generic runtime, and a new business concept can be introduced through types/configuration rather than bespoke application/database code.** --- # 31. Source Traceability This plan is derived from the current live documentation structure at: `https://docs.idiosyncrasy.co.uk/docs/` Key implementation decisions are owned by: - `governance/decisions.md` — D01–D10 settled architecture - `product/roadmap.md` — first executable milestone, Spearmint scope and implementation priority - `architecture/objects-and-types.md` — universal primitive and type contract - `architecture/business-model.md` — Business Graph, relationships and Business DNA - `architecture/identity-and-governance.md` — identity, authority, isolation and Policy enforcement - `architecture/time-and-events.md` — event/history/time semantics - `architecture/workflows-and-automation.md` — workflow/action/execution/recovery semantics - `architecture/views-and-content.md` — model-projection UI/content - `architecture/knowledge.md` — knowledge and provenance - `architecture/retrieval.md` — structured retrieval - `architecture/ai.md` — AI boundary - `architecture/analytics-and-evolution.md` — measurement/evolution - `implementation/architecture.md` — PHP/MariaDB runtime, physical mapping, Command pipeline, identity, workflow dispatcher and bootstrap - `implementation/development.md` — engineering boundaries and invariant tests - `implementation/security-and-operations.md` — operational/security controls - `implementation/ui-system.md` — UI implementation mechanism - `implementation/status.md` — current implementation evidence/status --- # 32. Final Principle Idiosyncrasy is not being implemented as a collection of applications with a common login. It is being implemented as a **generic business runtime** in which applications are projections of a shared, addressable, governed business model. The implementation must therefore optimise for: **semantic integrity → reusable runtime behaviour → deterministic execution → human operation → demonstrable business value → optional intelligence** not: **feature count → bespoke modules → AI generation → infrastructure complexity**. The first implementation should be deliberately small, but it must be structurally faithful to the architecture.