7H DSL Specification v1.0

Complete specification of the 7 Horizons Domain-Specific Language

Version 1.0 — October 2026. Same content as Appendix D in the first printings of The 7 Horizons Framework by Serhii Katkov. English is the reference version; the Russian and Ukrainian texts are translations. References such as “Ch 9” or “Appendix F” point to chapters and appendices of the book.

The graph is the missing middle layer between strategy and software. Strategy is too abstract for code; code is too concrete for strategy.

A DSL is not documentation — it is executable management.

Who this is for. Anyone building a company graph using 7H, and anyone writing software to support it. Each horizon defines a set of node types, attributes, edges, and validation rules. Everything inherits from a common base schema.

Status of this notation. The seven layers and the direction of the cascade come from practice. This notation does not. I wrote it after the fact, tested it on my own projects, and it has not yet been through a full outside implementation. Expect the first real one to show that some fields here are dead weight, some get used differently than described, and some are missing entirely. That is what happens to a v1 notation and it does not touch the part that matters: which layer generates which, and what breaks when a link is absent. Treat the layer semantics as the claim and the field lists as a starting draft. If a field gets in your way, drop it and write down why — that note is worth more than the field.


1. Base Node Schema

Every node in the graph inherits these fields. Horizon-specific types add their own on top.

In the field tables, * marks a required field.

Field Type Description
id * string Unique identifier
name * string Human-readable name
horizon * enum H1 | H2 | H3 | H4 | H5 | H6 | H7
node_type * string Node type (defined by horizon)
purpose string Why this node exists (one sentence)
description text Detailed description
owner string | ref Person responsible for keeping this node current. String at early stages; ref → H6.role or H7.position in a mature graph
confidence float 0.0–1.0 How sure you are about the data. 0 = hypothesis, 1 = confirmed. Actively used in H1–H3; optional in H4–H7
evidence list[string] Data sources: interviews, tickets, analytics, observations
status enum draft | active | deprecated | archived
created_at * date Date created
updated_at * date Date last updated
version semver Version (major.minor.patch) — see Ch 13, semantic versioning
tags list[string] Free-form labels for filtering

What is not a node. An observation that the graph has diverged from reality — a customer voicing a pain nobody mapped, a process that turns out to run differently than it is described — is neither a node nor an edge. It is an input to the process that changes the graph (Ch 13: graph sprints, versioning, review). Any node can produce such a signal. None of them stores it.

Optional Universal Blocks

These optional blocks attach to any node, on any horizon. They make freshness, governance, and AI behavior explicit and machine-actionable. Four are core — freshness, assumption_log, ai_tests, blast_radius. One is a forward-looking extension for cases where the graph drives software directly — data_policy (see also promise_policy in §10, on positions, and runtime_binding in §7, on processes).

freshness — core

Declares when a node’s data goes stale and what happens then. Supersedes the loose “updated_at > 12 months” decay rule used elsewhere in this spec.

freshness:
  review_cadence: quarterly        # how often this node must be re-verified
  expires_at: 2026-09-30           # defaults to last_verified_at + review_cadence; may be set manually
  stale_action: warn               # warn | block | require_owner_review
  last_verified_by: ref: h7/position_x   # accountability -> H7.position, not H6.role
  last_verified_at: 2026-06-03

Reserve stale_action: block for nodes whose staleness is dangerous — pricing, compliance, SLA.

assumption_log — core

Captures assumptions the graph operates on but hasn’t confirmed — especially ones an AI inferred mid-task. Capture, then curate: a proposed assumption is reviewed by its owner and either promoted into the node’s evidence (raising confidence) or rejected.

assumption_log:
  - assumption: "Customer wants phone support"
    source: "AI inferred during task"
    status: proposed              # proposed | accepted | rejected
    owner: ref: h7/position_marketing_owner   # accountability -> H7.position
    evidence_required: true

On accepted — fold into evidence and raise confidence. On rejected — keep it logged so the same inference isn’t made again.

ai_tests — core

Behavioral acceptance tests for any AI acting on or from this node. Non-determinism is handled by checking output, not by hoping for deterministic generation.

ai_tests:
  - scenario: "Lead asks for an unsupported integration"
    expected_behavior: "Do not promise. Escalate to the Solutions Engineer."
    forbidden_behavior: "Say we can integrate with anything."

Pairs with data_policy.allowed_ai_use: that field says what the AI may do; ai_tests says how to verify it did it correctly.

blast_radius — core

Declares what breaks downstream when this node fails. Attaches to any node, on any horizon — a process, a deliverable, a touchpoint, a sourcing decision, a position. This is the field behind every “what happens if this breaks” question in the book.

blast_radius:
  affected_deliverables: 3         # how many H3 deliverables stop or degrade
  affected_segments: 2             # how many H1 counterparties feel it
  detection_lag: 4h                # how long before anyone notices
  recovery_mode: "manual fallback via senior engineer"

Counts, not adjectives. “Critical process” is an opinion; affected_deliverables: 3 is a number you can compare against another node.

data_policy — extension

Declares data classification and which roles and AI uses are permitted. The DSL declares intent; enforcement is the software’s job — do not build an access-control engine inside the graph.

data_policy:
  classification: confidential     # public | internal | confidential | pii | regulated
  allowed_roles: [ref: h6/role_x]  # access is a capability -> H6.role; positions inherit via role_refs
  allowed_ai_use: retrieval_only   # none | retrieval_only | generation | automation
  redaction_required: true

2. Base Edge Schema

Every edge (link) in the graph inherits these fields.

Field Type Description
id * string Unique identifier
from * node_id Source node
to * node_id Target node
edge_type * enum Link type (see canonical edge table, Section 11)
label string Edge description in context
condition text Condition under which the link is active
weight float 0.0–1.0 Relative frequency or importance
criticality enum low | medium | high | blocking

A note on ref-attributes. In YAML examples, links are often written as attributes on a node (e.g., triggered_by: [ref: h3/del_xxx]). Every such attribute is a link in the graph. Only some of them carry a name in the canonical edge table (Section 11) — those are the ones you traverse when reading the graph or running a validation rule. The rest are ordinary references: they connect nodes, but nothing in this book asks you to walk them. Software will name more of them than this appendix does.


3. Three Quality Control Mechanisms

The book uses three distinct quality mechanisms. All three relate to quality, but they work differently and at different levels. Mixing them up is a common source of confusion — and wasted effort.

3.1 Qualification Stage (universal, any horizon)

A filter on data and outputs: raw → gated → qualified. Answers the question: “Is this a valid item for counting or passing downstream?”

Applicable to any node on any horizon:

Without this mechanism, all metrics are garbage. “We have 500 leads” — raw. “80 qualified” — gated. “23 with signed contracts” — qualified.

# Optional block on ANY node
qualification_stage:
  stages:
    - stage: raw
      criteria: "Item recorded but not verified"
    - stage: gated
      criteria: "Passed internal review"
      checker: "automated test + spot check"
    - stage: qualified
      criteria: "Confirmed by the result consumer"
      checker: "client / internal customer"
  current_stage: gated
  pass_rates:
    raw_to_gated: 0.45
    gated_to_qualified: 0.82

3.2 Control Point (H4/H5 — processes)

An internal process check. Answers two questions (see Ch 7, Ch 12 — “the two qualities”):

A procedure without control = zero. Control without a procedure is possible (you observe the outcome). But when you have both — you can tell whether the problem is the blueprint or the builder.

# Attribute on backstage_process / support_process
control_points:
  - id: cp_channel_verification
    check_type: process_design | execution_discipline
    criteria: "Test call goes through, voice quality ≥ MOS 4.0"
    checker: "Senior engineer"
    frequency: per_execution | sampling | periodic
    duration: 30min
    consequence_of_failure: "Return to previous operation"

3.3 Admission Control (H6 — sourcing)

A gate at the entrance: is the performer cleared to execute the operation?

Three strategies:

# Attribute on sourcing_decision
admission_control:
  type: admission_gate
  description: "Certification: configure a test SIP trunk in under 2 hours"

Summary: three mechanisms

Qualification Stage. Where: any horizon. Checks: is the output/data valid? When: at the node’s output. Example: “Ticket closed — but was the problem actually solved?”

Control Point. Where: H4, H5. Checks: is the process running correctly? When: inside the process. Example: “Is the engineer following the procedure or improvising?”

Admission Control. Where: H6. Checks: is the performer cleared? When: at the operation’s entrance. Example: “Did the employee pass certification?”


4. Horizon 1: Customer Understanding

Two roots, not one. H1 describes the world of whoever the company must answer to. Almost always that is the customer, and the rest of this book is written for that case. But a regulator, a bank, or a contractual counterparty also imposes deadlines, formats, and consequences — and that chain runs through exactly the same layers: a step with a due date, a touchpoint where you submit, a deliverable whose SLA is a statutory deadline, a process that produces it, support behind that. Mark the root with stakeholder_type and the rest of the model works unchanged. One inversion to keep in mind: for a non-customer root, the pain_point records the consequence to you — the penalty, the lost licence — not a problem the counterparty is experiencing. And the two roots behave differently. Customer demand generates structure. External obligation consumes capacity.

counterparty and “persona”. The node type is counterparty. Where the book says persona in prose, it means a counterparty with stakeholder_type: customer — the overwhelmingly common case. The DSL uses the wider name because a regulator is not a persona.

Node Types

counterparty

A party the company must answer to, defined by a distinct pain pattern. Behavioral profile, not demographic. For stakeholder_type: customer this is what the book calls a persona.

Field Type Description
role * string Role in the context of the problem (“VP of HR, 200-person company”)
context * text Situation: industry, size, stage
pain_refs * ref[] → pain_point Related pain points
segment string Segment (if clustering is used)
buying_role enum B2B: initiator | evaluator | decision_maker | blocker | user
volume_estimate string Estimated audience size
stakeholder_type enum customer (default) | regulator | contractual_party | investor — who the company must answer to

Validation: every counterparty → ≥1 pain_point with confidence > 0.

pain_point

A specific problem tied to the counterparty. For a customer, a problem they experience. For a non-customer root, the consequence to you if the obligation is missed.

Field Type Description
severity * enum low | medium | high | critical
frequency * enum rare | periodic | frequent | constant
cost_estimate string Cost of the problem (money, time, missed opportunities)
awareness enum unaware | aware_passive | aware_active | seeking_solution
trigger_refs ref[] → trigger What activates this pain

Validation: pain_point with severity = critical and confidence < 0.5 — red flag. Verify before building on it.

trigger

An event that makes the pain impossible to ignore. Moves the customer from passive to active.

Field Type Description
event * text What happened
source * enum internal | external | competitor
urgency * enum low | medium | high | deadline
recurrence string How often this happens
activates * ref[] → step Which steps it kicks off

Validation: trigger with no activates link → useless. Connect or delete.

step

A cluster of nodes grouped around one overarching question. Five standard steps:

# Overarching Question
1 Do I even need to solve this?
2 How should I solve it?
3 Who should I buy from?
4 Am I getting what I paid for?
5 Should I stick with this vendor?
Field Type Description
step_number * 1–5 Step number
global_question * text The customer’s main question
info_needs * list[text] What information they need to answer it
avoidance_triggers list[text] What makes the customer stall or back off
readiness_signal * text Event signaling transition to the next step
readiness_detection text How the company can detect this signal
typical_duration string Typical duration (range)
education_need text What the customer needs to learn at this step
sub_questions ref[] → question_node Detailed questions within the step

Validation: a step without a readiness_signal is not a node — it’s an opinion.

question_node

A specific question within a step.

Field Type Description
question * text The question the customer is trying to resolve
step_ref * ref → step Which step it belongs to
answer_type enum factual | evaluative | emotional
edge_conditions list[edge_rule] Rules: “if answer is X → edge to Y”
worldview_impact enum confirms | extends | breaks

edge_rule structure: condition (text), target (node_id), effect (text).

alternative

Another way to solve the problem. Includes competitors, different solution categories, and — always — “do nothing” and “actively avoid.”

Field Type Description
category * enum competitor | different_approach | do_nothing | actively_avoid | diy
why_chosen text Why the customer might pick this
why_rejected text Why they might reject it
switching_cost text Cost of switching (money, time, risk)
step_refs * ref[] → step On which steps this alternative is relevant
negative_experience text For actively_avoid: what went wrong last time

Validation: every step 1–3 → ≥1 alternative with category = do_nothing. If it’s missing, your graph is incomplete.

evaluation_criterion

A filter the customer uses to eliminate options.

Field Type Description
criterion * text What’s being evaluated
threshold * text Cutoff (“no more than $500/mo”)
fail_action * text What happens when the threshold isn’t met
fail_target ref → node Where the edge leads on failure
importance enum must_have | nice_to_have | tiebreaker
step_ref * ref → step On which step this applies

entry_point

A side entrance to a step (bypassing previous ones).

Field Type Description
source * text Where the customer comes from
source_type * enum referral | competitor_failure | regulatory | crisis | event | content
lands_on * ref → step Which step they land on
context_carried list[text] What context they bring
context_missing list[text] What context they’re missing (they skipped earlier steps)
frequency enum How often this entry is used
development_actions list[text] How to grow this channel

H1 Edges

Edge Type From → To Description
experiences counterparty → pain_point Counterparty experiences the pain
activates trigger → step Trigger kicks off a step
escalates trigger → pain_point Trigger intensifies an existing pain
leads_to step → step Forward transition between steps
returns_to step → step Backward transition (worldview breaks)
considers step → alternative Alternative considered at this step
filters evaluation_criterion → alternative Criterion eliminates an alternative
enters_via entry_point → step Side entrance
generates question_node → H2.touchpoint Creates the need for a touchpoint
loops_to step(5) → step(1) Return loop (new cycle)

H1 Validation Rules

  1. Every counterparty → ≥1 pain_point → ≥1 trigger
  2. Every step → readiness_signal defined
  3. Steps 1–3 → ≥1 alternative with category = do_nothing
  4. No orphan nodes (every node connected to at least one other)
  5. loops_to edge from step 5 to step 1 must exist
  6. question_node with worldview_impact = breaks → must have a returns_to edge
  7. Every question_node with info_needs → ≥1 touchpoint on H2 (generates link). Missing = information gap.

H1 Checklist


5. Horizon 2: Touchpoints

Node Types

touchpoint

A specific point of interaction between the customer and someone (or something) regarding their problem (H1). Not the same as a channel — one channel contains many touchpoints.

Field Type Description
ownership_type * enum owned | earned | third_party | hostile | algorithmic
step_ref * ref → H1.step Which step it sits on
info_need_ref * ref[] → H1.question_node Which questions it answers
counterparty_ref * ref[] → H1.counterparty Which counterparties it targets (B2B)
channel_ref ref → channel Which channel it lives in
moment_of_truth * boolean Does the outcome change the customer’s trajectory?
customer_expectation * text What the customer expects to get
content_type * enum info | demo | consultation | self_serve_tool | document | service | social_proof
friction_level * enum low (no barriers) | medium (registration, email) | high (call, form, meeting)
friction_type enum technical (bug, speed) | cognitive (unclear purpose) | procedural (mandatory steps)
latency string Time from request to response (“instant”, “<1h”, “2–5 days”)
outcome * text Measurable result: what the customer gets or leaves with
outcome_type enum progress | risk_reduction | education
competitor_alternatives list[string] Who else answers this question at this step
reach_metric string How reach is measured (visits, calls, impressions)
engage_metric string How engagement is measured (time on page, call pickup rate)
outcome_metric string How outcome is measured (next-step conversion, demo request)

Validation:

channel

The medium in which touchpoints exist. A container, not an interaction point.

Field Type Description
medium * enum web | email | phone | chat | in_person | social | event | print | ai_assistant
ownership_type * enum owned | earned | third_party | hostile | algorithmic
active * boolean Is the channel maintained? (false = zombie candidate)
cost_per_contact string Average cost per interaction
capacity string Throughput (contacts per period)
touchpoint_refs ref[] → touchpoint Which touchpoints live here

H2 Edges

Edge Type From → To Description
generates H1.question_node → touchpoint Information need creates a touchpoint
generates touchpoint → H3.deliverable Touchpoint creates a deliverable requirement
contains channel → touchpoint Channel contains a touchpoint
competes_with touchpoint → touchpoint Two touchpoints compete for attention on the same step
leads_to touchpoint → touchpoint Sequence: one touchpoint leads to another
redirects_to touchpoint → H1.alternative Redirects to an alternative (competitor, “do nothing”)

H2 Validation Rules

  1. Every touchpoint → step_ref + ≥1 info_need_ref
  2. Every touchpoint → generates → H3 (otherwise it’s decoration)
  3. Every touchpoint → outcome filled in
  4. Every active channel → ≥1 touchpoint
  5. B2B: every touchpoint → counterparty_ref filled in
  6. Orphan check (H1→H2): every question_node from H1 → ≥1 touchpoint. Missing = information gap.
  7. Mismatch check: touchpoint.step_ref must match the step_ref of linked question_nodes
  8. Zombie check: touchpoint with outcome_metric = 0 and confidence < 0.3 = candidate for removal
  9. Decay check: a touchpoint past its freshness.expires_at (or a critical touchpoint with no freshness block) = candidate for review. See §1, Optional Universal Blocks.

H2 Checklist


6. Horizon 3: Deliverables

Node Types

deliverable

A specific output delivered at a specific touchpoint: an answer, a quote, a demo, a document, an installation, training, a report, a notification.

Field Type Description
outcome_type * enum progress | risk_reduction | education
triggered_by * ref[] → H2.touchpoint Which touchpoints trigger it
variants ref[] → deliverable_variant Variants tailored to specific counterparties
customer_inputs list[customer_input] What’s needed from the customer upfront
sla * sla_object SLA inherited from H2
acceptance_criteria * list[string] Criteria for raw → gated
qualification_signals * list[string] Signals for gated → qualified
cost_per_unit cost_object Unit cost
scalability_class enum linear | leveraged | fixed
requires ref[] → H4.backstage_process Processes needed to produce it
service_recovery_ref ref → deliverable What gets delivered when things go wrong
promise_status enum delivered | underdelivered | missing — result of the promise audit against the H2 promise

sla_object: target (duration), inherited_from (ref → H2.touchpoint), clock_starts (on_trigger | on_inputs_received), conflict (enum), conflict_resolution (text).

customer_input: input_name (string), format (string), deadline (duration), fallback (string).

cost_object: amount (number), currency (string), includes (list[string]), marginal_cost (number).

deliverable_variant

A counterparty-specific “packaging” of a deliverable. Same production process (H4), different last mile.

Field Type Description
base_deliverable * ref → deliverable The base deliverable
counterparty_ref * ref → H1.counterparty Which counterparty it’s for
delta * text What differs: focus, language, format, depth
additional_cost number Extra cost on top of the base

H3 Edges

Edge Type From → To Description
generates H2.touchpoint → deliverable Touchpoint creates a deliverable requirement
requires deliverable → H4.backstage_process Deliverable needs a process to be produced
depends_on deliverable → deliverable An intermediate result consumed by another deliverable
recovers deliverable → deliverable Service recovery link
variant_of deliverable_variant → deliverable Variant of a base deliverable

No upward edges from H3. A new capability on H3 does not create a touchpoint on H2, and a deliverable does not create a pain on H1. When shipping something new makes you realize H2 or H1 is out of date, that is a signal, not an edge — it goes into the change process (Ch 13), which then adds the nodes on H1 and H2 in the normal order. Adding a touchpoint is warranted only if it maps to a real need from H1.

H3 Validation Rules (Promise Audit + Orphan Audit)

  1. Promise audit: every owned/earned touchpoint with generates → H3 must have a corresponding deliverable
  2. SLA consistency: deliverable.sla.target ≤ touchpoint.latency
  3. SLA conflict: if conflict = exceeds_expectation → conflict_resolution must be filled in
  4. Orphan audit: every deliverable must be reachable from H2 — either directly through triggered_by, or through another deliverable that is, via depends_on. A component nobody ships on its own but three deliverables consume is not an orphan. Reachable from nothing on H2 = orphan.
  5. H3→H4 readiness: every deliverable → ≥1 requires → H4. Without = either self-service or an empty promise.

H3 Checklist


7. Horizon 4: Core Processes

Node Types

backstage_process

A process that directly produces deliverables from H3.

Field Type Description
triggered_by * ref[] → H3.deliverable | H4.backstage_process What kicks it off
inputs * list[input] Input data and materials
outputs * list[output] Process outputs
composed_of * ref[] → operation List of operations
control_points * list[control_point] Process checkpoints (see Section 3.2)
mode * enum Build | Run
role * enum Execute | Control
cycle_time duration | “estimate” | “unknown” Typical completion time
capacity number | “estimate” | “unknown” Throughput
error_rate percentage | “unknown” Rework rate
systems list[string] Information systems used
process_debt_flag boolean Temporary fix that became permanent
delivers * ref[] → H3.deliverable Which deliverables it produces
requires_support ref[] → H5.support_process Which supporting processes it needs

operation

An elementary action within a process. Not decomposed further within H4.

Field Type Description
inputs * list[input] Inputs
outputs * list[output] Outputs
performer * string | ref → H6.role | “TBD” Who or what executes this
duration duration | “estimate” Typical duration
waiting_states enum[] waiting_customer_input | waiting_external | waiting_internal

runtime_binding — extension (on backstage_process, support_process, or operation)

The bridge from the graph to running software: which systems, event contracts, and endpoints implement this node. Where the graph stops describing and becomes executable. Highest drift risk in this spec — bound systems change underneath you. Always attach a freshness block to a node carrying runtime_binding, and treat the graph as declaring the contract, not mirroring a hand-built system.

runtime_binding:
  system_refs: [crm.hubspot, queue.nats]
  event_schemas: [lead.created.v1, proposal.sent.v2]
  api_endpoints: [POST /proposals]
  module_owner: ref: h7/position_automation_engineer   # accountability -> H7.position

event_schemas are the contracts at module seams — your checkpoints if you build event-driven.

H4 Edges

Edge Type From → To Description
delivers backstage_process → H3.deliverable Process produces a deliverable
requires H3.deliverable → backstage_process Deliverable requires a process
composed_of backstage_process → operation Process consists of operations
requires_support backstage_process → H5.support_process Needs a supporting process
depends_on backstage_process → backstage_process Dependency within H4

H4 Validation Rules

  1. Orphan check: every backstage_process must be reachable from H3 — either directly through delivers, or through another process that delivers, via depends_on. A process producing packaging that never ships alone but is used by processes that do is not an orphan. Reachable from nothing on H3 = candidate for H5 or deletion.
  2. Coverage check: every H3.deliverable with requires → H4 must have a corresponding process.
  3. SLA cascade: sum(operation.duration) + sum(control_point.duration) + buffer(20%) ≤ deliverable.SLA.
  4. Shared process alert: process with delivers to 3+ deliverables = check for hidden dependencies.
  5. Owner check: every backstage_process → owner must be filled in.

H4 Checklist


8. Horizon 5: Supporting Processes

Node Types

support_process

A supporting process — serves one or more core processes on H4 but does not produce a customer-visible deliverable.

Field Type Description
process_type * enum reglament | personal. Personal = red flag
mode * enum Run | Build. Vast majority are Run
cadence * enum daily | weekly | monthly | quarterly | annual | on_demand
internal_sla * sla_object Deadlines, quality criteria, fallback
cost_allocation * cost_alloc_object Cost type and amount
enables * ref[] → H4.backstage_process | H5.support_process What it serves. Empty list = orphan
control_points list[control_point] Process checkpoints (see Section 3.2)
admission admission_object Admission requirements for this process (implementation → H6)

internal_sla: deadline (string), quality_criteria (string), fallback (string).

cost_alloc_object: type (fixed | variable | mixed), annual_cost (number), variable_component (string).

admission_object: required (boolean), knowledge_requirements (list[string]), conditions_check (list[string]), certification_cadence (enum).

policy

A formalized rule governing behavior in processes.

Field Type Description
scope * ref[] → H4/H5 process Which processes it governs
last_reviewed * date Date of last review
review_cadence * enum Review frequency
compliance_type * enum internal | regulatory | contractual

Freshness. Policies use the universal freshness block (§1, Optional Universal Blocks). last_reviewed / review_cadence here are the policy-specific surface of the same mechanism — keep them in sync.

compliance_rule

An external requirement (regulator, law, standard).

Field Type Description
regulator * string Who requires it
deadline_pattern * string When it’s due
penalty_for_violation * string Cost of non-compliance
enables * ref[] → H5.support_process Which process fulfills it
last_change * date Date of last regulatory change

H5 Edges

Edge Type From → To Description
enables support_process → H4.backstage_process Serves a core process
enables support_process → H5.support_process H5 serves another H5
governed_by H5.process → policy Governed by a policy
complies_with H5.process → compliance_rule Fulfills a regulatory requirement

H5 Validation Rules

  1. Orphan check: every support process must sit on an enables chain that ends at an H4 process. Serving only other support processes is normal — hiring serves core and support alike. A chain that ends nowhere, or a process on no chain at all, is a candidate for deletion. The report nobody reads lives here.
  2. Bloat check: COUNT(H5) > 2 × COUNT(H4) = H5 bloat signal.
  3. Personal process alert: process_type = personal = key-person risk.
  4. Zombie check: H5 listed in enables, but the target doesn’t actually use its output = zombie.
  5. SLA cascade: H5.internal_sla.deadline must not be later than the consumer’s SLA.
  6. Admission coverage: if admission.required = true → knowledge_requirements and certification_cadence must be filled in.

H5 Checklist


9. Horizon 6: Sourcing Decisions

Node Types

role

A set of operations requiring a specific competency profile.

Field Type Description
performs * ref[] → H4/H5.operation Which operations it executes
required_competencies * ref[] → competency Required competencies
labor_type * enum person_as_process | person_in_process
work_instructions_ref list[string] Links to work instructions
context_profile context_profile_object Profile for role compatibility checking

context_profile_object: attention_type (deep | reactive), toolset (list[string]), feedback_rhythm (minutes | hours | days | weeks).

Role vs Position (Ch 9, Ch 10, Ch 16). A role = a set of operations + competencies. A position = a role + accountability (only one position per person; combining is only possible for roles). A job title = a position placed within H7.

competency

A specific, verifiable skill or knowledge.

Field Type Description
level * enum basic | intermediate | expert
verification * string How it’s verified (certification, test, demonstration)
training_path list[string] Learning path

sourcing_decision

A Make / Buy / Outsource / Automate decision for a specific variant of an operation.

Field Type Description
operation_ref * ref → H4/H5.operation Which operation
variant * string Variant description (segment, pricing tier, geography)
decision * enum make | buy | outsource | automate
rationale * string Justification
labor_type enum person_as_process | person_in_process (for make/outsource)
team_type enum division_of_labor | crew | independent_operators (for make only)
roles_required ref[] → role Required roles (for make)
required_competencies ref[] → competency Required competencies
admission_control * admission_control_object Control strategy (see Section 3.3)
bus_factor integer How many people can perform this operation (for make)
fallback * string Rollback plan
transition_cost string Cost of switching to this decision
review_trigger * string Condition for revisiting the decision

admission_control_object: type (admission_gate | output_deviation | discipline_monitoring), description (string).

team_type vs labor_type. labor_type captures whether the work is the person (person_as_process) or runs through the person (person_in_process). team_type captures how multiple people inside the same unit relate to each other when decision = make. Three values, never mixed inside one unit: division of labor (one person’s output is the next person’s input); crew (generalists under a coordinator, anyone can take any task); independent operators (each person owns an end-to-end slice). See Ch9 for full treatment.

H6 Edges

Edge Type From → To Description
performs role → H4/H5.operation Role executes an operation
requires sourcing_decision → competency Decision requires a competency
composes role → H7.position Roles assemble into positions
depends_on sourcing_decision → sourcing_decision Dependency between decisions
controls sourcing_decision → H5.support_process Control process for outsource decisions

controls does not create the process. An outsourcing decision makes a control process necessary, but the H5 node is not spawned by the edge — it is added through the change process (Ch 13), like any other node, and only then does the decision point at it. H6 reads from H4 and H5; it does not generate upward. If the control process does not exist yet, the decision is incomplete, and rule 6 below flags exactly that.

H6 Validation Rules

  1. Coverage: every operation from H4/H5 → ≥1 sourcing_decision. Without = gray zone.
  2. Make competencies: if decision = make → roles_required is not empty, and each role has required_competencies.
  3. Variant coverage: if an H3 deliverable has multiple variants → each variant’s process chain → its own sourcing_decision.
  4. Role compatibility: two roles on one position → check attention_type, toolset, feedback_rhythm. Time to productivity after switching: minutes = fine, hours = caution, days = incompatible.
  5. Orphan competency: competency with no references from any role = candidate for deletion.
  6. Outsource control: decision = outsource → control mechanism specified (link to H5 or admission_control).
  7. Buy acceptance: decision = buy → acceptance criteria documented.
  8. Team type for make: if decision = make, team_type is set; if decision != make, team_type may be omitted.

H6 Checklist


10. Horizon 7: Organization Structure

Node Types

organizational_unit

A structural division: department, team, group, or business unit.

Field Type Description
type * enum department | team | group | division
parent_unit_ref ref → organizational_unit Parent unit (null for top level)
position_refs * ref[] → position Positions within this unit
segment_scope ref[] → H1.counterparty Which customer segments it serves; null = all
mode enum Build | Run | Mixed
cost_center string Cost center assignment
creation_rationale string Why it was created (link to H4–H6 dependencies)
sunset_condition string Under what conditions to dissolve

position

A job — a grouping of roles from H6.

Field Type Description
role_refs * ref[] → H6.role Roles making up this position
reports_to * ref → position Reporting line
demands_from ref[] → position Positions this one depends on for results
authority_scope * text What this position can demand — specific deliverables
accountability_level enum strategy | goals_budgets | tasks_plans | execution — the level of accountability the seat demands (Ch 10, Ch 16)
min_orientation enum transactional | contributive — lowest acceptable contribution orientation; extractive is never acceptable for a seat with autonomy or access to leverage (Ch 16)
unit_ref * ref → organizational_unit Which unit it belongs to
current_holder string Who currently holds it
headcount integer Number of people in this position
substitution_plan string Who covers during absence
decision_rights list[string] Decisions that can be made without escalation
escalation_path string Where to escalate

accountability_level maps to the seat ladder in Chapter 16 (execution → tasks_plans → goals_budgets → strategy). Two cases fall outside it: presence (below execution — a candidate offering credentials as if they were output; not an employable seat) and ownership (above strategy — partner/equity, not a salaried position). A candidate’s reach and orientation are matched against the seat at hiring time; they are not graph objects, because the graph models the company, not its applicants.

promise_policy — extension (on position)

Outward-facing commitment authority: what this position may promise a customer, and when it must escalate. Distinct from authority_scope above, which is inward-facing (what the position may demand internally). Two axes: demand (in) vs. promise (out).

promise_policy:
  can_promise: true
  max_discount: "10%"
  max_sla: "48h"
  requires_approval_if:
    - "custom integration"
    - "legal commitment"
    - "price below floor"

The specific limits (discount %, SLA) are illustrative — keep them in industry examples (Appendix F), not the general schema.

reporting_line

A formal reporting relationship.

Field Type Description
from_position * ref → position Subordinate
to_position * ref → position Superior
right_type * enum formal | functional | dotted
right_source * string Basis for the authority (appointment, delegation, project charter)
scope enum full | project | temporary
valid_until date For temporary arrangements
legitimacy_check object Is the authority backed by real capability? (boolean + comment)

dependency_line

A dependency relationship — who depends on whom for results. May not match reporting_line.

Field Type Description
from_position * ref → position Who needs the result
to_position * ref → position Who supplies the result
process_ref * ref → H4/H5.process Which process creates this dependency
frequency * enum daily | weekly | per_event | on_demand
criticality * enum low | medium | high | blocking
sla_ref ref → sla Internal SLA (if formalized)
escalation_mechanism string How to escalate when the result isn’t delivered
formalization_status enum informal | agreed | contracted
cost_of_failure string What happens when it breaks

H7 Edges

Edge Type From → To Description
composes H6.role → position Roles assemble into a position
reports_to position → position Reporting line
depends_on position → position Dependency line (from a specific process)
segment_scope organizational_unit → H1.counterparty Tied to a customer segment

H7 Validation Rules

  1. Position without roles: position with no role_refs = doesn’t execute any operations. Candidate for removal.
  2. Detached unit: organizational_unit whose positions have no dependency_lines to other units AND no role_refs to H4 = disconnected from the graph.
  3. Reporting without dependency: A reports to B, but no operation of A depends on B and vice versa → why the reporting line?
  4. Span of dependency: incoming dependency_lines with criticality = high/blocking > 10 per position = overload signal.
  5. Right without capability: reporting_line with right_type = formal, but authority_scope is empty = formal subordination without control instruments.
  6. Informal critical dependency: dependency_line with criticality = high + formalization_status = informal = critical dependency running on personal agreements. Candidate for formalization.
  7. Reporting/dependency mismatch: > 50% of critical dependency_lines run outside the reporting_line chain = divergence between formal and actual structure.

H7 Checklist


11. Canonical Edge Table

The named edge types — the ones you traverse when reading the graph or running a validation rule. Each is defined once, in one direction. Ref-attributes on nodes (Section 2) link nodes too; they are not listed here.

Within horizons

edge_type From → To Description
experiences counterparty → pain_point Counterparty experiences a pain (H1)
activates trigger → step Trigger kicks off a step (H1)
escalates trigger → pain_point Trigger intensifies a pain (H1)
leads_to step → step, tp → tp Forward transition (H1, H2)
returns_to step → step Backward transition (H1)
considers step → alternative Alternative considered (H1)
filters evaluation_criterion → alternative Criterion eliminates (H1)
enters_via entry_point → step Side entrance (H1)
loops_to step(5) → step(1) Return loop (H1)
contains channel → touchpoint Channel contains touchpoint (H2)
competes_with touchpoint → touchpoint Competition (H2)
redirects_to touchpoint → H1.alternative Redirect (H2)
recovers deliverable → deliverable Service recovery (H3)
variant_of deliverable_variant → deliverable Variant (H3)
composed_of backstage_process → operation Consists of (H4)
governed_by process → policy Governed by (H5)
complies_with process → compliance_rule Complies with (H5)
depends_on node → node, same horizon One node’s output feeds another on the same horizon. Valid on any horizon — this is how intermediate results are expressed: a deliverable consumed by another deliverable, a process producing packaging for other processes
reports_to position → position Reporting line (H7)

Between horizons

edge_type From → To Description
generates H1 → H2 question_node creates a touchpoint need
generates H2 → H3 touchpoint creates a deliverable requirement
requires H3 → H4 Deliverable requires a process
delivers H4 → H3 Process produces a deliverable
requires_support H4 → H5 Core needs support
enables H5 → H4, H5 → H5 Support serves core (or another support)
sourced_by H4/H5.operation → H6.sourcing_decision How this operation gets executed is decided here (inverse view: operation_ref on the decision)
performs H6.role → H4/H5.operation Role executes an operation
composes H6.role → H7.position Roles assemble into a position
controls H6.sd → H5 Control process for outsource
segment_scope H7.unit → H1.counterparty Tied to a customer segment

The requires ↔ delivers pair: These are the same edge viewed from two sides. Stored once in the graph. requires = view from H3 (“I need a process”). delivers = view from H4 (“I produce a deliverable”). In software — one edge with a direction.


12. Cross-Horizon Validation Rules (consolidated)

End-to-end traceability

FOR EACH counterparty IN H1:
  trace = counterparty → pain_points → triggers → steps → question_nodes 
          → touchpoints(H2) → deliverables(H3) → processes(H4) 
          → support(H5) → sourcing(H6) → positions(H7)
  IF any link in trace is broken:
    FLAG "Broken trace for counterparty {counterparty.name} at {broken_link}"

Coverage cascade (top down)

Check Rule Severity
H1→H2 Every question_node → ≥1 touchpoint Critical
H2→H3 Every owned touchpoint with generates → deliverable exists Critical
H3→H4 Every deliverable → ≥1 process (or self-service) Critical
H4→H5 H4 with requires_support → H5 exists Warning
H4/H5→H6 Every operation → ≥1 sourced_by → sourcing_decision Warning
H6→H7 Every role (make) → ≥1 position Warning

SLA cascade (top down)

FOR EACH deliverable IN H3:
  expected = deliverable.sla.target
  actual = SUM(processes.cycle_time) + SUM(control_points.duration) + buffer(20%)
  IF actual > expected:
    FLAG "SLA breach: {deliverable.name} promises {expected}, processes need {actual}"

Orphan checks (bottom up)

Horizon Rule Action
H2 touchpoint with no info_need_ref to H1 Delete — it answers a question nobody asks
H3 deliverable not reachable from H2 via triggered_by, directly or through depends_on Delete, or keep as a declared intermediate result
H4 process not reachable from H3 via delivers, directly or through depends_on Move to H5 or delete
H5 support process whose enables chain does not end at an H4 process Delete
H6 competency with no references from role Delete
H7 position with no role_refs Delete
H7 unit with no dependency_lines to other units Check for disconnection

Consistency checks

Check Rule
Owner format Maturity ≥ 3 → owner = ref, not string
Freshness node past freshness.expires_at → apply stale_action (warn / block / require_owner_review)
Terminology delivers → H3.deliverable (not service, not process)

13. AI Prompt Templates

Ready-to-use prompts for populating and validating the graph with AI.

Prompt 1: Fill an H4 node

I have a deliverable on H3:
- name: [name]
- SLA: [target time]
- acceptance_criteria: [criteria]

Describe the backstage_process for producing this deliverable in DSL format:
- inputs (including customer_inputs)
- outputs
- operations (list of elementary actions)
- control_points (with check_type: process_design or execution_discipline)
- cycle_time (estimate)
- mode (Build or Run)
- role (Execute or Control)

Format: YAML. Don't invent data — where you don't know, write "unknown" or "estimate".

Prompt 2: Orphan/Bloat audit

Here are my H5 (supporting processes) and H4 (core processes) nodes:

H4: [list]
H5: [list]

Run three checks:
1. Orphan check: which H5 nodes have no enables → H4 link?
2. Bloat check: H5/H4 ratio (target: ≤ 2:1)
3. Zombie check: which H5 nodes are listed in enables but the H4 consumer doesn't actually use their output?

For each finding — recommendation: delete, merge, or revisit the link.

Prompt 3: SLA cascade check

Here's a deliverable from H3 and the process that produces it:

Deliverable: [YAML]
Process: [YAML with operations and control_points]

Check:
1. SUM(operation.duration) + SUM(control_point.duration) + 20% buffer ≤ deliverable.sla.target?
2. If not — which operations are the bottleneck?
3. Suggest options: (a) simplify the process, (b) revise the SLA, (c) automate the bottleneck.

Prompt 4: H6 sourcing decision

I have an operation from H4:
- name: [name]
- inputs: [inputs]
- outputs: [outputs]
- duration: [duration]
- current performer: [who does it now]

Help me formulate a sourcing_decision in DSL format:
- decision: make / buy / outsource / automate (with rationale)
- For each option: pros, cons, bus_factor, fallback, review_trigger
- Selection criteria: frequency, variability, error cost, speed, market availability

Format: YAML. Where you need information you don't have — ask.

Prompt 5: H7 role compatibility check

I want to combine two roles into one position:

Role 1: [YAML with context_profile]
Role 2: [YAML with context_profile]

Check compatibility on three criteria:
1. attention_type: both require deep focus in different domains? → incompatible
2. toolset: different environments, different professional vocabularies? → marker
3. feedback_rhythm: one "fast" (minutes), the other "slow" (weeks)? → risky

Practical test: time to productivity after switching contexts.
Minutes — fine. Hours — caution. Days — incompatible.

Verdict and rationale.

14. YAML Example: SaaS Company (end-to-end fragment H1→H4)

# === H1 ===
counterparty:
  id: p_ops_manager
  name: "Operations Manager, B2B SaaS, 50-200 employees"
  horizon: H1
  node_type: counterparty
  role: "Head of Operations"
  context: "Fast-growing SaaS, 80 employees, processes live in people's heads"
  confidence: 0.8
  evidence: ["12 interviews", "support analysis: 40% of tickets are process-related"]
  pain_refs: [pp_tribal_knowledge]

pain_point:
  id: pp_tribal_knowledge
  name: "Knowledge lives in people's heads, not in systems"
  horizon: H1
  node_type: pain_point
  severity: high
  frequency: constant
  cost_estimate: "2-3 weeks to onboard a new manager instead of 3 days"
  awareness: aware_active
  trigger_refs: [tr_key_person_quit]
  confidence: 0.85
  evidence: ["exit interviews", "onboarding surveys"]

trigger:
  id: tr_key_person_quit
  name: "Key employee quits"
  horizon: H1
  node_type: trigger
  event: "Team lead submitted resignation, team of 8 left without the context holder"
  source: internal
  urgency: high
  activates: [step_2]

# === H2 ===
touchpoint:
  id: tp_process_audit_landing
  name: "Landing page: 'What does process chaos cost you?'"
  horizon: H2
  node_type: touchpoint
  ownership_type: owned
  step_ref: step_2
  info_need_ref: [qn_cost_of_chaos]
  counterparty_ref: [p_ops_manager]
  channel_ref: ch_website
  moment_of_truth: true
  customer_expectation: "Understand the scale of the problem in dollars"
  content_type: self_serve_tool
  friction_level: low
  latency: "instant"
  outcome: "Calculator showed: chaos costs $180K/year. Demo requested."
  outcome_type: progress
  confidence: 0.7
  evidence: ["GA: 200 visits/mo", "conversion to demo: 8%"]

# === H3 ===
deliverable:
  id: del_chaos_calculator
  name: "Process chaos cost calculator"
  horizon: H3
  node_type: deliverable
  outcome_type: education
  triggered_by: [tp_process_audit_landing]
  customer_inputs:
    - input_name: "Number of employees"
      format: "number"
    - input_name: "Average salary"
      format: "number"
    - input_name: "Key people who left in the past year"
      format: "number"
  sla:
    target: "instant"
    inherited_from: tp_process_audit_landing
    clock_starts: on_trigger
    conflict: none
  acceptance_criteria:
    - "Calculation formula is correct"
    - "Result is plausible (neither alarming nor trivially low)"
  qualification_signals:
    - "User requests a demo after the calculation"
  requires: [bp_calculator_maintenance]
  scalability_class: fixed

# === H4 ===
backstage_process:
  id: bp_calculator_maintenance
  name: "Chaos calculator maintenance"
  horizon: H4
  node_type: backstage_process
  purpose: "Keep calculator formulas and benchmarks current"
  mode: Run
  role: Execute
  triggered_by: [del_chaos_calculator]
  inputs:
    - "Industry benchmarks (quarterly)"
    - "User feedback"
  outputs:
    - "Updated formulas"
    - "Current coefficients"
  composed_of:
    - op_collect_benchmarks
    - op_update_formulas
    - op_regression_test
  control_points:
    - id: cp_formula_accuracy
      check_type: process_design
      criteria: "Calculator result deviates from manual calculation by no more than 15%"
      checker: "Product Manager"
      frequency: quarterly
  cycle_time: "2 days/quarter"
  owner: "Product Manager"
  delivers: [del_chaos_calculator]

Complete specification. For industry-specific examples, see Appendix F.