================================================================================
SDOA GOVERNANCE OUTLINE
Version: 5.0
Date: 2026-06-17
Classification: Internal — Development Team & Project Leads
================================================================================

This document is the operational governance reference for the Self-Describing
Object Architecture (SDOA) as adopted on the SDOAvX project. All developers
and project leads working in this codebase are expected to know and follow
the rules in this document.

--------------------------------------------------------------------------------
SECTION 1 — GOVERNANCE OVERVIEW
--------------------------------------------------------------------------------

SDOA governance is the set of rules that ensure the architecture remains clean,
discoverable, and scalable as the codebase grows. Governance is not bureaucracy
— it is the mechanism by which the architecture enforces its own principles.

Governance is enforced at three levels:
  1. Structural: The directory layout and file placement rules make violations
     visually obvious.
  2. Declarative: The manifest system makes hidden dependencies impossible.
  3. Automated (v5.0): The ProbationOfficer sovereign validates newly synthesized
     modules against all governance rules in a sandbox before acceptance.

Key principle: Governance rules are not flexible on a case-by-case basis. If a
rule appears to prevent a legitimate need, the correct response is to raise an
amendment — not to bypass the rule.

--------------------------------------------------------------------------------
SECTION 2 — SOVEREIGNTY RULES
--------------------------------------------------------------------------------

2.1 Each Module Owns Its Own Lineage
--------------------------------------
A sovereign module owns:
  - Its source file(s)
  - Its manifest
  - Its CSS file(s)
  - Its data files (schemas, configs, catalogs it consumes)
  - Its variants (in its own variants/ subdirectory)

A sovereign module does NOT own:
  - Anything inside another module's folder
  - Any shared "global" data directory
  - Any other module's manifest

2.2 No Cross-Sovereign Mutations
----------------------------------
No module may directly modify another module's internal state, files, or
implementation. Cross-module communication is permitted only through:
  - Declared interfaces in the manifest (requires / dependencies)
  - The EventBus (publish/subscribe pattern)
  - The StateStore API (get / set / watch)
  - Explicit service calls through the registry

Reaching into another module and modifying its internals — even for a "quick
fix" — is a sovereignty violation.

2.3 Variant Rules
------------------
A variant is an alternate implementation of an existing sovereign. Variants are
branches, not versions. Version increments stay within a single sovereign.
Variants are separate sovereigns that declare their parentage.

Rule: Variants must live in the parent sovereign's variants/ subdirectory.

  Correct:
    ui/features/Workspace/variants/compact/Workspace.compact.feature.js

  Incorrect:
    /legacy/Workspace.compact.feature.js
    /experimental/Workspace.compact.feature.js
    /global/Workspace.compact.feature.js

Variants are never created inside prohibited directories. They stay with their
parent sovereign at all times unless formally deprecated and removed from the
active registry (at which point they move to the appropriate legacy/ directory
within their domain).

--------------------------------------------------------------------------------
SECTION 3 — MANIFEST COMPLIANCE REQUIREMENTS
--------------------------------------------------------------------------------

3.1 SDOA v1.2 Mandatory Fields
--------------------------------
Every SDOA module must declare all eight mandatory v1.2 fields. A module missing
any of these fields will be rejected by the registry at startup.

  id            The module's unique identifier. No two modules share an id.
  type          The module type (primitive, feature, adapter, service, workflow,
                repository, engine, dashboard, task, validator)
  version       Semantic version string (e.g., "1.0.0", "4.0.05")
  runtime       Execution environment: Browser | NodeJS | Universal | Rust |
                Python | C++ | COBOL | VB
  capabilities  Array of capability strings this module provides to the system
  dependencies  Array of module ids this module requires (v1.2 name)
  docs          Object with at minimum a "description" string
  last_modified ISO 8601 timestamp of the most recent change

v4.0 added the following fields (required for v4.0+ modules):
  layer         1 (feature), 2 (primitive), or 3 (adapter/service/workflow)
  requires      Module ids this module depends on (v4.0 alias for dependencies)
  dataFiles     Paths to external .json data files loaded at runtime
  lifecycle     Array of lifecycle method names
  actions       Object containing commands, events, accepts, slots

v5.0 added the following fields (required for v5.0 modules):
  operationalRole  System role (registrar/captain/conductor/coach/
                   probation-officer/assembly-line/triage/savant)
  optimization     Object: {priority, assertionSuite}

3.2 Non-Compliant File Handling
---------------------------------
Some files cannot be made fully manifest-compliant. Examples: third-party
libraries, legacy files from before SDOA was adopted, host environment files.

Rule: All files that are touched must have an SDOA v1.2 manifest. If the file
cannot be made compliant, the manifest must declare this explicitly:

  "non-sdoa-compliant": true

This field must appear in the manifest of any file that does not meet full
compliance. The registry logs these files but does not reject them. Undeclared
non-compliance is not acceptable — a file without a manifest and without a
non-sdoa-compliant declaration is a governance violation.

> All files that we touch, always (forward and backward), should have an SDOA
> v1.2 manifest. If the file is non-compliant, put it in the manifest.

--------------------------------------------------------------------------------
SECTION 4 — MODULE LIFECYCLE POLICY
--------------------------------------------------------------------------------

4.1 Frontend Lifecycle Contract (Primitives and Features)
-----------------------------------------------------------
Every UI module (primitive or feature) must implement all five lifecycle methods.
These must be implemented in this order and for these purposes only:

  init(config)      First call. Register event listeners, load data files, set
                    up internal state. DO NOT touch the DOM. The container does
                    not exist yet.

  mount(container)  The module's DOM is now attached. Render initial state.
                    Receive the container element. All rendering happens here.

  update(newState)  State has changed. Re-render only what changed. Avoid full
                    re-renders. This method should be cheap.

  unmount()         The module's DOM is being removed. Remove ALL event listeners
                    added in mount(). Cancel pending requests. Undo mount().

  destroy()         Module is permanently retired. Release memory, close
                    connections. Undo init(). Called after unmount().

Lifecycle violations (these are bugs, not style choices):
  - Calling mount() before init(): initialization order must be respected
  - Forgetting to remove event listeners in unmount(): creates ghost listeners
    that accumulate over time and cause memory leaks and unpredictable behavior
  - Doing DOM work in init(): the container does not exist at that stage
  - Calling destroy() without first calling unmount(): skips cleanup

4.2 Backend Lifecycle Contract (Workflows and Repositories)
-------------------------------------------------------------
Backend modules implement a three-method contract:

  init(registry)   Called once at server startup. Register self with the
                   registry, load dependencies, open connections.

  run(payload)     Called per-request. Execute the operation. Return a
                   standardized response: {ok: true, data:{...}} or
                   {ok: false, error: "..."}.

  dispose()        Called at server shutdown. Clean up connections, flush
                   pending writes, release resources.

--------------------------------------------------------------------------------
SECTION 5 — LINE-LIMIT POLICY (v4.1 AMENDMENT)
--------------------------------------------------------------------------------

5.1 Per-Type Line Limits
--------------------------

| Module Type | Min Lines | Max Lines | Hard Limit | Action if Exceeded           |
|-------------|-----------|-----------|------------|------------------------------|
| Primitive   |    150    |    250    |    ~500    | Split into sub-primitives    |
| Feature     |    200    |    350    |    ~500    | Extract to adapters/sub-feats|
| Adapter     |    200    |    350    |    ~500    | Split by concern             |
| Workflow    |    200    |    400    |    ~500    | Extract helpers to repos     |
| Repository  |    200    |    400    |    ~500    | Split by entity type         |

5.2 Hard Limit Enforcement
---------------------------
The hard limit of ~500 lines is inviolable. No module type, no complexity
argument, and no deadline pressure justifies exceeding it.

If a module has reached 500 lines, it is doing too many things. This is the
architecture telling you that a refactor is overdue.

In v5.0, the ProbationOfficer sovereign automatically flags modules that cross
their configured bounds and marks them for decomposition by the evolution loop.

5.3 What Triggers a Refactor
------------------------------
A refactor is required when:
  - A module exceeds its maximum line count for its type
  - A planned addition would push it past its maximum
  - A module is clearly doing more than one thing (dual responsibility)

The v4.1 Amendment acknowledges that well-organized modules in complex domains
legitimately require more lines than the original v4.0 targets. The amendment
raises the targets, not the hard limit. The original v4.0 limits (Primitive 150,
Feature 200, Adapter 200, Workflow 200) are superseded by the v4.1 targets
above.

> When in doubt: split first, optimize later. A split module is always easier
> to understand than a large one, and the performance cost is negligible.

--------------------------------------------------------------------------------
SECTION 6 — VARIANT POLICY
--------------------------------------------------------------------------------

6.1 When a File Becomes a Variant vs. Canonical
-------------------------------------------------
A file is a variant (not a new independent sovereign) when:
  - It fulfills the same functional contract as an existing sovereign
  - But with a different implementation approach (e.g., different tech, different
    optimization target, different deployment context)

A file is a new canonical sovereign when:
  - It serves a functionally different purpose from any existing module
  - It has no parent sovereign that it is an alternate form of

If unsure, prefer variant. Creating redundant canonical modules is harder to
clean up than merging an unnecessary variant back into its parent.

6.2 Naming Rules for Variants
-------------------------------
Variant module IDs follow the pattern: "[ParentId].[variant-descriptor]"
  Examples:
    Workspace.feature.compact   (compact variant of Workspace.feature)
    Queue.service.redis         (Redis variant of Queue.service)
    MathSolver.engine.wasm      (WebAssembly variant of MathSolver.engine)

Variant file names follow: [ParentName].[variant-descriptor].[type].[ext]
  Examples:
    Workspace.compact.feature.js
    Queue.redis.service.js

6.3 Variant Manifest Requirements
-----------------------------------
Every variant must have a full SDOA v1.2 Manifest. Required fields:
  id            Unique, following the pattern above
  type          Same as parent (feature, service, engine, etc.)
  version       Variant's own version number, independent of parent
  runtime       Execution environment
  capabilities  What this variant provides
  dependencies  What it needs
  docs          Description of what makes this variant different from parent
  last_modified ISO 8601 timestamp
  variant_of    ID of the parent sovereign module (mandatory for variants)

Optional compliance field:
  compliance    Set to {"non-sdoa-compliant": true} if variant cannot comply

Minimal compliant variant manifest example:
  {
    "id": "Workspace.feature.compact",
    "type": "feature",
    "version": "1.0.0",
    "runtime": "js",
    "variant_of": "Workspace.feature",
    "capabilities": ["ui:workspace:compact"],
    "dependencies": [],
    "docs": "Compact variant optimized for small screens and dense layouts.",
    "last_modified": "2026-06-17T15:14:00Z"
  }

--------------------------------------------------------------------------------
SECTION 7 — DIRECTORY PLACEMENT POLICY
--------------------------------------------------------------------------------

7.1 Canonical Directory Structure
-----------------------------------
sdoavx/
  ui/               UI sovereigns (all CSS, UI schemas, UI data files)
    tokens.css      Global design tokens — only place for global CSS variables
    primitives/     Layer 2: one folder per primitive, CSS co-located
    features/       Layer 1: one folder per feature, CSS co-located
    dashboards/     Full UI pages
    adapters/       Frontend Layer 3 adapters
    services/       Frontend cross-cutting services (EventBus)
    data/           Externalized data owned by UI modules
  substrate/        Backend infrastructure sovereigns
    services/       Infrastructure-layer Node.js services
    adapters/       Backend-side adapters
    bridges/        Cross-language IPC bridges
    engines/        Substrate-level engines
    workflows/      Backend operation modules (auto-discovered)
  evolution/        Polyglot computation engines and legacy handling
    engines/        Domain-specific engines (Rust, Python, JS, etc.)
    legacy/         Formally deprecated modules (graveyard only)
    experimental/   System-level experiments (not for individual variants)
    translations/   Cross-language port versions
  authorities/      System governance and routing
    bootstrap/      System startup sequences
    router/         Dynamic routing configuration
    conductor/      Event mesh management
    registrar/      Module registry and manifest index
    captain/        Application state sovereignty
  documentation/
  environment/      .env templates, scripts, docker, OS configs

7.2 Prohibited Directories
----------------------------
Never create these directories. They violate sovereignty and become dumping
grounds that make the codebase undiscoverable:

  /assets/
  /static/
  /deps/
  /resources/
  /misc/
  /global/

If you find yourself needing one of these names, determine which sovereign owns
the files in question and place them there instead.

7.3 File Type Routing Rules
-----------------------------

CSS files:
  Co-located with the primitive or feature that owns them.
  Global tokens only in ui/tokens.css.
  Never in a global /styles/ directory.

Binary files (.bin, .wasm, compiled artifacts):
  Live with the engine or substrate module that consumes them.
  Example: evolution/engines/Solvers/SolverV3/solver.wasm

JSON / JSN files — by category:
  Configuration (authority-owned): authorities/registrar/registry.jsn
  Schema (module-owned): ui/features/Workspace/schema.jsn
  Engine data (evolution-owned): evolution/engines/TextClassifier/v2/metadata.jsn

Other dependency files (.txt, .cfg, .yaml, .proto):
  Same rule: file lives with the sovereign that consumes it.
  Protocol buffers: substrate/bridges/grpc/messages.proto
  Engine configs: evolution/engines/Billing/v3/config.yaml
  UI strings: ui/features/Projects/strings.json
  Authority policies: authorities/captain/policy.yaml

Scripts (shell, bootstrap, environment):
  environment/setup.sh
  environment/dev.env
  environment/docker-compose.yaml

Rust source:
  Lives with the engine or service sovereign that defines it.

Python source:
  Lives with the workflow or engine sovereign that defines it.

--------------------------------------------------------------------------------
SECTION 8 — NAMING CONVENTIONS
--------------------------------------------------------------------------------

8.1 File Naming Patterns by Type

| Module Type   | Convention              | Example                        |
|---------------|-------------------------|--------------------------------|
| Primitive     | PascalCase.prim.js      | Button.prim.js                 |
| Feature       | PascalCase.feature.js   | UserSettings.feature.js        |
| Adapter       | PascalCase.adapter.js   | BackendConnector.adapter.js    |
| Workflow      | PascalCase.workflow.js  | CreateItem.workflow.js         |
| Repository    | PascalCase.repository.js| Item.repository.js             |
| Service       | PascalCase.service.js   | EventBus.service.js            |
| Primitive CSS | PascalCase.prim.css     | Button.prim.css                |
| Feature CSS   | PascalCase.feature.css  | Dashboard.feature.css          |
| Schema files  | kebab-case.schema.json  | user-settings.schema.json      |
| Variant file  | Parent.variant.type.js  | Workspace.compact.feature.js   |

8.2 Module ID Conventions
  Format: Name.type  (e.g., "Button.prim", "Settings.feature", "Chat.workflow")
  Variant format: Name.type.variant (e.g., "Workspace.feature.compact")
  IDs are unique across the entire system — no two modules share an id.

8.3 CSS Class Prefix Convention
  All CSS classes for a primitive must use the prefix: sdoa-{primitive-name}
  Examples: sdoa-button, sdoa-modal, sdoa-panel, sdoa-tab-group

8.4 Event Name Convention
  Format: module:action  (e.g., "backend:statusChanged", "chat:messageSent")

8.5 State Key Convention
  Format: camelCase  (e.g., "currentProject", "backendStatus", "attachedFiles")

--------------------------------------------------------------------------------
SECTION 9 — DEDUPLICATION POLICY
--------------------------------------------------------------------------------

9.1 Same Name + Same Extension = Variants
-------------------------------------------
If two files have the same name and extension but different implementations,
they are variants of the same sovereign.

Action:
  - Determine which is canonical (typically the newer, more-used version)
  - Move the non-canonical version to the parent sovereign's variants/
    subdirectory with a descriptive variant name
  - Add a manifest with variant_of pointing to the canonical module

9.2 Same Name + Same Extension + Same File Size = Exact Duplicate
------------------------------------------------------------------
If two files have the same name, extension, and file size, they are exact
duplicates. One is redundant.

Action:
  - Verify contents are identical
  - Delete the copy that is farther from the canonical location
  - If both are equidistant, delete the one with the older last_modified

9.3 Deduplication During Migration
------------------------------------
During the v3 -> v4/v5 migration, file discovery may surface duplicates from
the legacy structure. Apply the above rules before finalizing any module's
placement. Do not carry duplicates forward into the new structure.

--------------------------------------------------------------------------------
SECTION 10 — AMENDMENT PROCESS
--------------------------------------------------------------------------------

10.1 How to Propose an Architecture Amendment
----------------------------------------------
An amendment is a formal change to any governance rule, line limit, manifest
field requirement, or structural policy.

To propose an amendment:
  1. Identify the specific rule being changed and the reason for the change
  2. Describe the change clearly, including before and after
  3. Identify all modules affected by the change
  4. Propose a migration path for existing non-compliant modules
  5. Present to project leads for ratification

Amendments are not changes made informally. A one-off exception is not an
amendment — it is a violation. If a rule needs a permanent exception, the
rule itself needs to be amended.

10.2 Version Increment Rules for Amendments
--------------------------------------------
  - Amendments that add new optional fields: minor version increment (e.g., 4.0 -> 4.1)
  - Amendments that add new mandatory fields: major version increment (e.g., 4.x -> 5.0)
  - Amendments that change limits or policies: minor version increment with
    amendment name (e.g., "v4.1 Line-Limit Amendment")

All documents referencing the superseded rule must be updated to reference the
new rule after ratification.

10.3 Ratification Record
-------------------------
Ratified amendments must be recorded with:
  - Amendment name
  - Version number
  - Date of ratification
  - Summary of the change
  - Ratifying authority (project lead, team, or named resolution)

Known ratified amendments:
  C1 Resolution (2026-06-17): Canonical name confirmed as "Self-Describing
    Object Architecture." Supersedes "Service-Oriented Dispatcher Architecture."

  v4.1 Line-Limit Amendment (May/June 2026): Per-type line limit targets
    revised upward from v4.0 originals. Hard limit of ~500 lines established.
    Per-type targets: Primitives 150-250, Features 200-350, Adapters 200-350,
    Workflows 200-400, Repositories 200-400.

--------------------------------------------------------------------------------
SECTION 11 — HYBRID INFRASTRUCTURE & CLOUD WORKER GOVERNANCE
--------------------------------------------------------------------------------

11.1 Cloud Worker Isolation
---------------------------
The cloud worker (mcp-worker) is explicitly classified as external serverless routing infrastructure and falls OUTSIDE the local SDOA constraint-solving validation checks. 

Rules:
  - It does not require SDOA manifest headers on its routing/entrypoint files.
  - It is hosted on Cloudflare Workers (V8 isolate serverless platform) and is not subject to directory placement or line-limit constraints of local sovereigns.
  - It communicates with the SDOA local engine strictly via the Federated Innovation Sync Protocol (FISP) JSON envelopes.

================================================================================
END OF SDOA GOVERNANCE OUTLINE v5.0
================================================================================
