Skip to content

State model

Physical Notion realization of Initiative, workstream, Product, Asset, and Decision/Event state for M1 (D-01 / G3). Ownership, operations, and conflict rules remain in the authority model. Component boundaries remain in system components.

Schema revision: state-model.v2 (proposed; Gate A pending)
Committed revision: c519ee3b5e19792222d1401f66df61ffbaca5dd5 (c519ee3 on origin/main; prior bind e0cf737 / 356c1e9)
Paired Asset contract: asset-registry.v2
Tracking: hector-sanchez-eu/conductor#3
Brief: M1 brief

Gate A approval must name this exact revision (state-model.v2). This document does not authorize database creation. Gate A approves the schema design. Gate D approves mutation/import.

Locked M0 constraints

  • Conductor does not write routine Notion state. Executing agents persist IDs and writeback.
  • Notion is authoritative for Initiative, workstream, Product, Asset, and Decision/Event state.
  • The Conductor identity allocator mints IDs; executing agents persist them.
  • Assets are enduring systems; Initiatives are work that creates or changes outcomes.
  • Decision/Event ownership follows the authority model (line active_role vs Portfolio Manager).

Target workspace (Gate A input)

Field Proposed value Status
Notion workspace sdhector workspace (867ec393-2263-8154-bd17-000319357256) Confirmed via Notion MCP fetch self (2026-07-24)
Parent page Conductor State — page ID 3a7ec393-2263-818b-bce3-daa9a46b9220open Created 2026-07-24 (workspace-level parent; nine DBs still Gate D only)
Schema revision property Every database page carries schema_version = state-model.v2. Assets also carry asset_registry_version = asset-registry.v2. Proposed

Until Gate D approval, do not create the nine databases under this parent. Schema design review may proceed; Gate A approval still requires a committed schema revision in git.

Multi-agent access (default: Notion CLI)

Default for every agent: official Notion CLI ntn + Bitwarden-backed token. See notion-access.md.

Path When
ntn + NOTION_API_TOKEN / ntn login Preferred — Cursor, VPS, OpenClaw, CI
Notion REST API (same token) Conductor read adapters after Gate C
Cursor Notion MCP Optional interactive only — not the shared default

Do not treat Cursor plugin OAuth as the shared secret store.

Database layout

Nine databases (Gate A / state-model.v2):

Database Title Purpose
initiatives Conductor Initiatives Organizational work contracts
workstreams Conductor Workstreams One line contribution per Initiative
products Conductor Products Product evaluation state
assets Conductor Assets Enduring systems (see asset-registry.md)
decisions_events Conductor Decisions/Events Append-oriented history (may link Assets)
asset_repositories Conductor Asset Repositories Typed repo links for Assets
asset_environments Conductor Asset Environments Typed deploy/URL rows for Assets
asset_evidence Conductor Asset Evidence One-row-per-reference provenance, verification, and promotion evidence
asset_relationships Conductor Asset Relationships One-row-per-edge typed relationships with per-edge review

Workstreams and Decisions/Events are not nested child pages of Initiative. Repositories, environments, provenance, and relationships are not free-text or parallel ordered fields on the Asset row.

Relations

text Initiative 1──* Workstream Initiative *──* Product Initiative 1──* Decision/Event Workstream *──* Decision/Event Asset *──* Initiative Asset 1──* AssetRepository Asset 1──* AssetEnvironment Asset 1──* AssetEvidence (provenance / verification / promotion refs) Asset *──* AssetRelationship (as source or target; edge SoR) Decision/Event *──* Asset (related_assets — verification/promotion/events) AssetEvidence *──* Decision/Event (optional linked_event) AssetRelationship *──* AssetEvidence AssetRelationship *──* Decision/Event

Relationship kinds are not stored as Asset-wide checkboxes or unordered multi-relations without edge metadata. The asset_relationships database is authoritative for typed edges.

Identifier mint and persist

Identifier Format (convention) Minted by Persisted by Store
initiative_id init.<ulid> Identity allocator Executing agent for Portfolio Manager Initiatives DB
workstream_id ws.<ulid> Identity allocator Executing agent for current active_role Workstreams DB
product_id prod.<ulid> Identity allocator Executing agent for Product Manager Products DB
asset_id asset.<ulid> Identity allocator Executing agent for Portfolio Manager Assets DB
event_id evt.<ulid> Identity allocator Executing agent for owning role Decisions/Events DB
repo_id arep.<ulid> Identity allocator Executing agent for Portfolio Manager Asset Repositories DB
env_id aenv.<ulid> Identity allocator Executing agent for Portfolio Manager Asset Environments DB
evidence_id aev.<ulid> Identity allocator Executing agent for Portfolio Manager Asset Evidence DB
relationship_id arel.<ulid> Identity allocator Executing agent for Portfolio Manager Asset Relationships DB

Rules:

  1. Minting alone is not project-state writeback.
  2. Persist must be idempotent on the stable ID (create-if-absent or update-by-ID).
  3. Notion page ID is an adapter locator, not the Conductor stable ID.
  4. Authorization IDs remain control-plane artifacts; they are not Decision/Event IDs.
  5. Child Asset rows (arep / aenv): uniqueness is (asset_id, url) for repositories and (asset_id, url, environment) for environments — re-persist updates the existing row by stable ID; never create a second row for the same uniqueness key.

Initiatives database

Property Notion type Required Notes
Name title yes Human title
initiative_id rich_text yes Stable ID
schema_version select yes state-model.v2
outcome rich_text yes
definition_of_done rich_text yes
owner rich_text yes Role ID, e.g. role.portfolio-manager
priority select yes p0 p1 p2 p3
portfolio_status select yes intake active parked done killed
review_date date when active/parked
archetype select after classify software-product content-product services-product
related_initiatives relation → Initiatives optional Parent/child/enabling/derived; use relationship_kind on events for nuance
products relation → Products optional
assets relation → Assets optional
privacy_class select yes See organization profile; default internal
context_version rich_text yes Opaque version string bumped on material state change
last_writeback_at date optional Last successful completion writeback
notes_summary rich_text optional Short Portfolio summary only

Removed vs superseded sketch (integrations/notion_schema.yml in the repo root):

  • Do not use active_line or attending_lines. Concurrent participation is represented by Workstream rows.
  • Do not treat github_issue_url as required. Optional evidence may appear on workstreams.
  • Do not embed software_stage on the Initiative; Software stage lives on the Software workstream.

Authoritative writer

Executing agent acting for Portfolio Manager (see authority model). Conductor: read / validate only.

Workstreams database

Property Notion type Required Notes
Name title yes Display label, e.g. Software — Implement
workstream_id rich_text yes
schema_version select yes state-model.v2
initiative relation → Initiatives yes Exactly one
line select yes portfolio product software editorial services operate
stage rich_text yes Exact stage ID from org-map-model.md
active_role rich_text while active One role ID
status select yes planned active blocked waiting done cancelled
next_action rich_text while active/blocked
bindings rich_text stage-dependent JSON or structured text of inventory bindings
evidence_links rich_text stage-dependent URLs and short labels
privacy_class select yes
context_version rich_text yes
completion_records rich_text optional Latest completion JSON (see below) or pointer

Portfolio workstream is persistent for every Initiative. Delivery-line workstreams are optional and concurrent.

Authoritative writer

Executing agent for the current active_role. Cross-workstream conflicts escalate to Portfolio Manager.

Products database

Property Notion type Required Notes
Name title yes
product_id rich_text yes
schema_version select yes state-model.v2
initiatives relation → Initiatives yes One or more
profile select yes venture bootstrap
stage select yes Discover Explore Score Build-gate Ship-signal Archive (store exact IDs)
status rich_text yes Free-form micro-status
score_snapshot rich_text at Score+
evidence_links rich_text optional
privacy_class select yes
context_version rich_text yes

estate_urls from the old sketch move to the Assets database. Products do not store estate SoR.

Authoritative writer

Executing agent under Product Manager.

Assets database

Field-level Asset contract is defined in asset-registry.md. Physical properties for Gate A (state-model.v2 / asset-registry.v2):

Property Notion type Required Notes
Name title yes Primary display name
asset_id rich_text yes Stable ID
schema_version select yes Always state-model.v2 (physical layout revision)
asset_registry_version select yes Always asset-registry.v2 (Asset contract revision)
review_status select yes candidate reviewed rejected superseded-record
aliases multi_select optional Former names / slugs
purpose rich_text for reviewed
users_needs rich_text for reviewed
capabilities rich_text for reviewed Comparable capability bullets
lifecycle_status select yes proposed prototype active maintained superseded archived
estate select yes prototype lab portfolio-org
stack rich_text when known Descriptive; never sole equivalence evidence
deploy_shape select when known static dynamic-socket dynamic-always-on saas unknown
runtime_profile select when known Compatibility axis (e.g. browser node python systemd unknown)
privacy_class select yes
related_initiatives relation → Initiatives optional
last_verified_at date for reviewed Must not be in the future
extraction_notes rich_text candidate only Never authoritative
portability_gap rich_text when no portable canonical ref Explicit gap

Removed in v2 (lossy / non-edge-specific):

  • provenance_kinds + ordered provenance_refs — replaced by asset_evidence rows
  • Asset-wide relationship_human_reviewed and Asset-side rel_* multi-relations as SoR — replaced by asset_relationships edges
  • Lone verification_evidence URL on Asset — moved into asset_evidence (evidence_class=verification) plus optional Decision/Event via related_assets

Asset Repositories (asset_repositories)

Property Notion type Required
Name title yes
repo_id rich_text yes
schema_version select yes
asset relation → Assets yes (exactly one)
url url yes
role select yes
privacy_class select yes

Uniqueness / idempotency: one row per (asset_id, url). Upsert by repo_id or by uniqueness key.

Asset Environments (asset_environments)

Property Notion type Required
Name title yes
env_id rich_text yes
schema_version select yes
asset relation → Assets yes
url url yes
environment select yes
verified_at date optional
privacy_class select yes

Uniqueness / idempotency: one row per (asset_id, url, environment). Upsert by env_id or by uniqueness key.

Asset Evidence (asset_evidence) — lossless one-row-per-reference

Property Notion type Required Notes
Name title yes Short label
evidence_id rich_text yes Stable ID aev.<ulid>
schema_version select yes state-model.v2
asset relation → Assets yes Exactly one Asset
evidence_class select yes provenance verification promotion
kind select yes github-repo notion-page deploy-url human decision-event other
ref_url url when URL-shaped Preferred locator
ref_text rich_text when non-URL Package id, note, etc.
noted_by rich_text yes Role or human identity
noted_at date yes Must not be in the future
linked_event relation → Decisions/Events optional Ties verification/promotion to an event
privacy_class select yes

Rules: each reference is one row. Repeated kinds are allowed (two github-repo rows). Do not encode lists by ordering across Asset properties.

Asset Relationships (asset_relationships) — edge SoR

Property Notion type Required Notes
Name title yes e.g. alpha duplicate_of beta
relationship_id rich_text yes arel.<ulid>
schema_version select yes state-model.v2
source_asset relation → Assets yes Exactly one
target_asset relation → Assets yes Exactly one
kind select yes related depends_on fork_of duplicate_of replaces replaced_by extends
review_status select yes candidate human-reviewed rejected
reviewer rich_text when human-reviewed
reviewed_at date when human-reviewed Must not be in the future
asserted_need rich_text when kind=extends and human-reviewed Exact need statement this edge supports for extend
asserted_delta rich_text when kind=extends and human-reviewed Exact delta justified for extend
evidence_rows relation → Asset Evidence optional
evidence_event relation → Decisions/Events optional Resolved to evt.* by the physical mapper
evidence_url url optional
notes rich_text optional
privacy_class select yes

Human-required kinds (duplicate_of, replaces, replaced_by, fork_of, extends) must be review_status=human-reviewed with reviewer + reviewed_at before they may support reuse/extend evidence. For extends, asserted_need and asserted_delta are required on the physical edge and must match the evaluator request.

Config locator names:

  • CONDUCTOR_NOTION_ASSET_REPOS_DATABASE_ID
  • CONDUCTOR_NOTION_ASSET_ENVS_DATABASE_ID
  • CONDUCTOR_NOTION_ASSET_EVIDENCE_DATABASE_ID
  • CONDUCTOR_NOTION_ASSET_RELATIONSHIPS_DATABASE_ID

Authoritative writer

Delegated humans or agents with Asset write permission under Portfolio Manager. Never the Conductor compiler.

Decisions/Events database

Append-oriented. Prefer create-new over mutate-in-place. Corrections supersede via supersedes relation, not silent rewrite of history meaning.

Property Notion type Required Notes
Name title yes Short event label
event_id rich_text yes
schema_version select yes state-model.v2
initiative relation → Initiatives yes
workstream relation → Workstreams when line event / completion
related_assets relation → Assets when Asset verification/promotion/estate event Enables Asset-linked evidence
event_class select yes line-workstream portfolio-disposition completion asset-verification asset-promotion estate-comparison exception other
event_type rich_text yes e.g. stage-transition, decision, writeback, asset-verify, estate-comparison, kill
actor_role rich_text yes
agent_identity rich_text for completion Client/agent identity
occurred_at date yes
written_at date for completion Writeback timestamp
authorization_id rich_text when from authorized work Control-plane ID reference only
pack_version rich_text when applicable
context_version rich_text when applicable
summary rich_text yes
actions rich_text for completion What was done
decisions rich_text for completion Material decisions
unresolved_items rich_text for completion Open gaps
next_action rich_text for completion Concrete next action
result select for completion success partial-failure failed
idempotency_key rich_text for completion authorization_id + writeback class
evidence_links rich_text optional One URL per line
privacy_class select yes
supersedes relation → Decisions/Events optional
asserted_need rich_text when event_class is estate-comparison or portfolio-disposition estate comparison Exact need statement for EstateComparison
claim_ids multi_select or rich_text (one ID per line) when estate comparison carries claims Must match IDs inside comparison_payload
disposition_ids multi_select or rich_text (one ID per line) when estate comparison carries dispositions Must match IDs inside comparison_payload
comparison_payload rich_text (JSON) when estate comparison Immutable semantic payload: claims (polarity/text/citations), dispositions (status/negative_claim/evidence), optional no_material_gaps + evidence, optional extend {base_asset_id,delta}

Completion/writeback conceptual fields from G3 map 1:1 onto these properties (plus initiative / workstream relations for stable ID resolution). Do not collapse writeback into summary alone.

Asset verification and promotion: create a Decision/Event with event_class asset-verification or asset-promotion, set related_assets, and create matching asset_evidence rows with linked_event pointing at that event.

EstateComparison (Gate B authority boundary)

Decisive reuse / extend / new outcomes require an immutable EstateComparison persisted as a Decisions/Events row:

  • event_class must be estate-comparison or portfolio-disposition (never other / asset-verification for comparison authority)
  • event_type is typically estate-comparison
  • asserted_need, actor_role, occurred_at, privacy_class, and related_assets bind the request
  • comparison_payload JSON holds the full semantic payload (claim polarity/text/citations, disposition status/negative_claim/evidence, optional no-gap + extend). Caller dictionaries cannot override this payload.
  • claim_ids / disposition_ids must match the payload when present

The evaluator consumes only validated typed EstateComparison records plus an opaque adapter-produced ExhaustiveSnapshot. Without both, the only legal outcome is insufficient-context.

See asset-registry.md and service/conductor/integrations/read_adapters/estate_comparison.py.

Ownership split (physical)

event_class Decision owner Writer
line-workstream Current active_role Executing agent for that role
portfolio-disposition Portfolio Manager Executing agent for Portfolio Manager
completion Current active_role Executing agent for that role
asset-verification / asset-promotion Portfolio Manager Delegated Asset writers under Portfolio Manager

Plan-authorization audit content is not stored here (authorization audit store).

Completion / writeback record (G3)

The authorized plan names exact Notion and production updates. The executing agent writes an idempotent completion record as a Decisions/Events row with the completion properties above.

Required fields (physical mapping)

Field Physical property
initiative_id Resolved via initiative relation → Initiative.initiative_id
workstream_id Resolved via workstream relation → Workstream.workstream_id
agent_identity agent_identity
authorization_id authorization_id
pack_version pack_version
context_version context_version
actions actions
evidence_links evidence_links
decisions decisions
unresolved_items unresolved_items
next_action next_action
result result
idempotency_key idempotency_key
written_at written_at

Storage

  1. Primary: create a Decisions/Events row with event_class=completion and event_type=writeback.
  2. Mirror summary: update Workstream next_action, status, evidence_links, context_version, and Initiative last_writeback_at / context_version as named by the plan.
  3. Success is not claimed until Notion writeback succeeds or result=partial-failure is explicit.
  4. Conductor may read / verify on next consultation. Conductor must not silently repair missing writeback.

Required views

View Database Purpose
Portfolio Active Initiatives portfolio_status in active/intake; sorted by priority, review_date
Portfolio Review Due Initiatives review_date ≤ today
Concurrent Workstreams Workstreams Filter by Initiative; show line/stage/status/role
Product Pipeline Products By profile and stage
Asset Estate Assets By estate, lifecycle, review_status
Asset Candidates Assets review_status=candidate
Asset Evidence by Asset Asset Evidence Filter by asset; class provenance/verification/promotion
Asset Relationship Edges Asset Relationships By kind and review_status
Event Timeline Decisions/Events By Initiative, newest first
Writeback Gaps Decisions/Events + Workstreams Active workstreams with stale/missing completion

Bootstrap and migration

Existing sketch

integrations/notion_schema.yml and the write orchestrator under service/conductor/integrations/ are superseded sketches for Initiatives/Products only. They use retired active_line / attending_lines fields and mutate Notion from Conductor, which violates M0.

M1 path:

  1. Gate A: approve this schema revision (state-model.v2) and fill Target workspace.
  2. Gate C: approve read credentials and scopes.
  3. Gate D: approve create/import plan.
  4. Create the nine databases under the confirmed parent.
  5. Optionally import any existing Initiative/Product pages as candidates mapped to state-model.v2 (strip superseded fields; create Workstream rows for concurrent lines).
  6. Do not extend the write orchestrator as Conductor's steady-state write path. Legacy mutation MCP tools and schema bootstrap remain disabled by default (CONDUCTOR_LEGACY_WRITES_ENABLED); unavailable in production. Executing agents own writeback; Conductor adapters are read-only (see read-access-contract.md).

Rollback

Failure Recovery
Partial DB create Delete newly created empty DBs; leave prior sketch untouched
Bad import batch Tag imported pages schema_version=rollback-pending; restore from Notion history or re-import from dry-run export
Wrong parent Move databases only after Hector confirms; record new locators in org profile config names

Rollback rehearsal is required evidence before Gate D import completes.

Conflict with indexes

Derived estate indexes and caches cannot override Notion. If index and Notion disagree, Notion wins; the index is rebuilt.

Gate A approval checklist

Hector approves Gate A when commenting Conductor-Gate-A: approve on issue #3, naming revision state-model.v2, and confirming:

  1. Nine-database layout (including asset_evidence and asset_relationships).
  2. Workspace and parent page filled in the Target workspace table (owner action — blocked until provided).
  3. Identifier formats and mint/persist flow.
  4. Completion/writeback physical properties on Decisions/Events, including related_assets.
  5. Lossless evidence and per-edge relationship models (no parallel ordered provenance fields; no Asset-wide relationship review checkbox).
  6. Migration stance vs existing Initiatives/Products sketch.
  7. Legacy mutation surface remains disabled by default.
  8. Physical schema_version=state-model.v2 on all nine databases; Assets also set asset_registry_version=asset-registry.v2.
  9. Approval names a committed schema revision (git SHA / PR), not only an in-doc label.