Runtime — SOFIA's first implementation uses Claude Code and CLAUDE.md files. The concepts described here (persona, isolation, artifacts) are provider-agnostic — only the runtime layer is specific to a provider. Some sections describe Claude Code specifics. Latter versions implement other providers.

Implementation

How H2A is implemented today — and how it could be implemented tomorrow.


Principle

H2A defines the semantics of interactions (entities, invariants, protocol/observational layers). This document describes the current implementation. A different implementation would be H2A-conformant as long as it respects the semantics defined in h2a.md, friction.md, contribution.md, and exchange.md.

Current implementation

Stack

Component Choice Role
Artifact format Markdown + YAML frontmatter Human-readable and audit-readable, no software dependency
Persistence git Immutable history, diff, blame — trace per session
Space structure Filesystem directories One directory = one space. Natural isolation
Shared space shared/ at instance root Sole channel between personas
Instance marker sofia.md file at root Identifies a SOFIA deployment and its version
AI provider Claude Code CLAUDE.md as persona instruction, hooks, project memory

Traceability conventions

Commits (recommended):

{persona}: {short summary} ({date})

One commit per session.

Session summaries:

{space}/sessions/{YYYY-MM-DD}-{HHmm}-{persona}.md

At each closure, the persona creates a new file. The HHmm is the closure time (not the boot time). A long session with multiple closures produces multiple files.

Instance structure

Scaffolding is minimal — only elements necessary for the protocol are created at initialization. The internal organization of shared/ (subdirectories, artifact naming conventions, archiving) is an instance convention, not standard implementation.

instance/                        ← scaffolding (create-instance)
├── sofia.md                     ← instance marker
├── shared/                      ← shared space (exchange bus)
│   ├── conventions.md           ← instance-specific conventions
│   └── orga/                    ← team organization
│       ├── personas/            ← persona files
│       └── contextes/           ← contexts per persona-product
├── {space}/                     ← one per persona
│   ├── CLAUDE.md                ← persona instructions (provider)
│   └── sessions/                ← session summaries
└── ...

The protocol requires shared/ as the sole channel and artifacts with frontmatter. How the instance organizes its artifacts in shared/ (subdirectories, naming, archiving) is a local decision documented in conventions.md.

Repo ownership (MAY)

When an instance spans multiple repositories, conventions.md MAY declare a ## Repo ownership section mapping external repo paths to persona owners.

## Repo ownership

| Repo | Path | Owner |
|------|------|-------|
| product-repo | doc/architecture/ | @architect |
| product-repo | (rest) | @dev |

This is useful when personas from the same instance work in different parts of the same external repo. The workspace field in persona files covers the instance-internal space; repo ownership covers external repos.

Installing the protocol on a persona

The H2A protocol is installed via the context (shared/orga/contextes/contexte-{persona}-{product}.md), not via the persona file. The persona file defines the role (instance-agnostic). The context installs the instance rules.

Each context MUST contain an ## H2A Protocol section that:

Without this section, the persona will not trace friction — this is the most common prescription/usage gap.

Inline friction template (to include in each context):

Friction format: {symbol} [{marker}] {description} — [{initiative}] → {resolution}
Markers: ✓ [sound], ~ [contestable], ⚡ [simplification], ◐ [blind_spot], ✗ [refuted]
Initiative: [persona] or [PO]
Resolution (SHOULD): → ratified, → contested, → revised, → rejected
Lineage: if amending a prior friction, add (ref: {source-id}/{index})

The template is a safety net — the persona has the format in view when producing, without rereading an external file.

Frontmatter

Every artifact deposited in the shared space carries a YAML frontmatter. No accents in values.

Artifacts:

---
from: persona-emitter
to: persona-recipient
nature: signal           # signal | question | request | response
status: new              # new | read | done
date: YYYY-MM-DD
ref: artifact-identifier # SHOULD when nature = response
---

The ref field links a response to its source artifact. The identifier is the filename without extension (e.g., note-aurele-localisation-doc-site-livia). For cross-instance artifacts, the instance-source field indicates the originating instance.

Sessions:

---
persona: persona-name
date: YYYY-MM-DD
session: "HHmm"
---

Archiving

When an artifact moves to status: done, it is moved to archives/ in the parent directory.

Status lifecycle

Status Meaning
new Deposited, not yet read by the recipient
read Read by the recipient
done The recipient has acted on it

Retrocompat: the parser also accepts FR values (nouveau, lu, traite).

Artifact resolution

When an artifact is processed, each point SHOULD carry a resolution tag in the document body (not in the frontmatter — an artifact often contains multiple points).

Convention: the recipient annotates each point with → ratified, → contested, → revised, or → rejected before archiving.

Example:

## Proposition A
→ ratified

## Proposition B
→ rejected (short justification)

## Proposition C
→ revised (detail on what changes)

Retrocompat: the parser also accepts FR tags (ratifie, conteste, revise, rejete).

Friction in session summaries

Section ## Orchestrator friction (SHOULD — see exchange.md §Sessions, observational layer).

Each line carries the dimensions defined in friction.md, rendered as:

## Orchestrator friction
- [marker] description — [initiative] → resolution

Markers: rendered as bracketed keywords + visual symbol in instance conventions.

Protocol (friction.md) Markdown rendering
[sound] ✓ or [sound]
[contestable] ~ or [contestable]
[simplification] ⚡ or [simplification]
[blind_spot] ◐ or [blind_spot]
[refuted] ✗ or [refuted]

Retrocompat: the parser also accepts FR brackets ([juste], [angle-mort], [faux]).

Visual symbols (✓/~/⚡/◐/✗) are an instance convenience. Bracketed keywords are authoritative for audit.

Initiative: [persona] or [PO] — who initiated the friction subject.

Resolution: epistemic gesture tag after the arrow . See protocol/friction.md §Resolution.

Protocol (friction.md) Markdown rendering
ratified → ratified
contested → contested
revised → revised
rejected → rejected

The resolution tag is set per friction point, not per section.

Example:

## Orchestrator friction
- ✓ [sound] the Toulmin mapping illuminates without constraining — [PO] → ratified
- ~ [contestable] the Toulmin mapping is suggestive, not established — [PO] → revised
- ◐ [blind_spot] scaffolding absent from the Böckeler review — [aurele] → ratified

Lineage (antecedent dimension)

When a friction amends a prior friction (see protocol/friction.md §Lineage), the antecedent dimension is materialized by a ref: field at the end of the line:

- ✓ [sound] the protocol/observational distinction covers the case — [aurele] → ratified (ref: 2026-04-10-1430-aurele/3)

Format: ref: {source-id}/{index} where:

Implementation rules:

The exchange and emitter dimensions are implicit: the exchange is the current session, the emitter is the persona authoring the summary.

reportPattern in session summaries

Section ## reportPattern (MAY — observational layer for the observation, protocol layer for the counter).

The persona records the trigger and the orchestrator's choice:

## reportPattern
- Theme: [theme] — N rejected frictions (sessions YYYY-MM-DD, ...)
- Choice: LLM error | conviction | resistance
- Justification: ...

The audit counts triggers and the distribution of choices (protocol counter).

Contribution in session summaries

Section ## Flow (MAY — see exchange.md §Sessions, observational layer).

Each line carries the dimensions defined in contribution.md, rendered as:

## Flow
- {direction}:{type} — description

Direction: H (human brings) or A (assistant brings). Type: substance, structure, contestation, decision.

Counting (optional): a summary line at the end of the section.

Example:

## Flow
- H:substance — Böckeler article, request for opinion
- A:substance — scaffolding lineage absent from Böckeler
- A:structure — three levels of harness/SOFIA complementarity
- H:decision — keep keyword notation

H:2 (substance 1, decision 1) | A:2 (substance 1, structure 1)

The session dimension is implicit: it is the current session.

Operations — filesystem implementation

Mapping of H2A operations (see protocol/h2a.md) to the current implementation.

Operation Mode Concrete gesture
openSession() manual The orchestrator launches a terminal in the persona's workspace (or resumes an existing Claude Code session)
closeSession() manual The orchestrator gives the signal. The persona rereads shared/conventions.md, then produces the summary, prepares the commit. The orchestrator executes the commit
send() manual The orchestrator instructs the persona. The persona rereads shared/conventions.md, then produces the artifact (note, review, feature) and deposits in the recipient's shared/. Cross-instance: the artifact goes to the recipient instance's shared/, not the emitter's
receive() manual The orchestrator opens a session with the recipient and presents the artifact. The recipient reads, processes, and MAY produce a response (with ref: to the source artifact)
markRead() manual The orchestrator sets status: read in the artifact's frontmatter
markDone() manual The orchestrator sets status: done in the frontmatter — the artifact is then moved to archives/
qualifyFriction() automatic The persona pre-fills the ## Orchestrator friction section at closure. The orchestrator validates or corrects
qualifyContribution() automatic The persona pre-fills the ## Flow section at closure. The orchestrator validates or corrects
reportPattern() automatic The persona detects a thematic convergence of rejections during the session. It challenges the orchestrator with the observation + 3 argued hypotheses. The orchestrator responds with their choice + justification. At closure, the persona records in a ## reportPattern section of the summary

Manual = the orchestrator triggers with an explicit gesture. Automatic = the persona produces at session closure, the orchestrator validates.

The persona MUST NOT close on its own or deposit an artifact without orchestrator instruction.

Tooling

Tool Role
binding/filesystem/audit-instance.py Verifies instance protocol conformity
binding/filesystem/create-instance.py Scaffolds a new instance
sofia.md Meta persona — instantiates, audits. Protocol operator

What is implementation vs protocol

Element Protocol (h2a.md) Implementation (this doc)
"Each session produces a trace"
"The trace is a .md file committed in git"
"The markers are [sound] [contestable] etc."
"The markers are in a Markdown file"
"The shared space is the sole channel"
"The shared space is a shared/ directory"
"The instance is identifiable"
"The instance is identified by a sofia.md file"
"Friction carries 5 dimensions"
"Friction is a Markdown line with symbol + keyword + initiative"
"Contribution carries direction and type"
"Contribution is a `{H\ A}:{type} — description` line"
"Friction carries a resolution tag"
"The resolution tag is rendered → ratified at end of Markdown line"
"A resolution can evolve between sessions with ref:"
"The ref: is rendered (ref: session-id/n) at end of Markdown line"
"reportPattern() produces an observation + 3 hypotheses + qualification"
"reportPattern is a ## reportPattern section in the summary"
"The reportPattern choice counter is auditable"

Perspectives

HTTP API

H2A could be implemented as a REST API:

Database

Session summaries, artifacts, and friction markers could live in a relational or document database. Git history would be replaced by an event log.

MCP / A2A interoperability

H2A covers the human-assistant layer. MCP and A2A cover the agent-tools and agent-agent layers. A complete system could combine all three:

Wire format

If H2A evolves toward a technical protocol, a wire format (JSON, protobuf, etc.) and an interoperability spec will be needed. This is not in the current scope.


Audit rules — binding/filesystem

Reference for all checks performed by analysis/cli/probe.py.


Check ID taxonomy

Format: {level}{category}{number}

Prefix Level Category Conditioned by
PS Protocol Structure always
PP Protocol Personas always
PA Protocol Artifacts always
PF Protocol Format always
AN Artifact Note --artifacts notes
AR Artifact Review --artifacts reviews
AF Artifact Feature --artifacts features
IS Instance Structure not --protocol-only
IN Instance Naming not --protocol-only
IR Instance Roadmap not --protocol-only

Severity

Severity Meaning
fail Blocks conformity — the instance is not valid
warn Should be fixed — degraded quality
info Informational — no action required

Protocol checks

Protocol Structure (PS)

ID Rule Severity Source
PS1 sofia.md present at root fail protocol/exchange.md — instance marker
PS2 shared/ directory present fail protocol/exchange.md — shared space
PS3 shared/conventions.md present warn protocol/exchange.md — exchange rules
PS4 At least 1 workspace with CLAUDE.md fail protocol/exchange.md — persona space
PS5 Each workspace has sessions/ warn protocol/exchange.md — session traces

Protocol Personas (PP)

ID Rule Severity Source
PP1 shared/orga/personas/ has persona-*.md files warn core/model.md — persona entity
PP2 Each workspace maps to a persona file warn protocol/exchange.md — persona space
PP3 Persona files have 7 required dimensions (identity, stance, scope, deliverables, prohibitions, challenge, collaboration) warn core/model.md §7 dimensions
PP4 Each persona has a context file in shared/orga/contextes/ info Instance convention

Protocol Artifacts (PA)

Global checks on ALL .md files in shared/ (excluding conventions.md, roadmap-*.md, orga/, audits/).

ID Rule Severity Source
PA1 All artifacts have frontmatter warn protocol/exchange.md §Artifacts
PA2 All artifacts have required fields (from, to, nature, status, date) warn protocol/exchange.md §Specific dimensions
PA3 All status values are valid (new/read/done or FR equivalents) warn protocol/exchange.md §Lifecycle

Protocol Format (PF)

ID Rule Severity Source
PF1 Sessions have conformant frontmatter (persona, date) info protocol/exchange.md §Sessions

Artifact checks

Each declared artifact type gets 5 standard checks. Add --artifacts notes,reviews,features to control which types are audited.

Artifact Note (AN)

ID Rule Severity
AN1 shared/notes/ present with archives/ info
AN2 Notes have frontmatter warn
AN3 Required fields (from, to, nature, status, date) warn
AN4 Naming convention note-{subject}-{author}.md info
AN5 Done files archived warn

Artifact Review (AR)

ID Rule Severity
AR1 shared/review/ present with archives/ info
AR2 Reviews have frontmatter warn
AR3 Required fields (from, to, nature, status, date, subject) warn
AR4 Naming convention review-{subject}-{author}.md info
AR5 Done files archived warn

Artifact Feature (AF)

ID Rule Severity
AF1 shared/features/ present info
AF2 Features have frontmatter warn
AF3 Required fields (from, to, nature, status, date) warn

Other artifact types (dynamic)

Any type declared in ## Artifact types of shared/conventions.md gets the same 5 checks (A{X}1-A{X}5) with a dynamic prefix. Common optional types:

Type Prefix Directory Naming Notes
features AF shared/features/ feature-{name}.md Feature specs
adr AA shared/adr/ adr-{number}-{title}.md Instance-level decision records
team-orga AT shared/orga/ team-orga.md Team organization (single file)

These are not protocol — they are instance conventions. An instance that doesn't use ADRs or team-orga simply doesn't declare them.

Instance checks

Instance Structure (IS)

ID Rule Severity
IS1 shared/orga/ present info
IS2 Roadmaps in shared/ info
IS3 No accents in frontmatter values info
IS4 Files in archives/ have status done info

Instance Naming (IN)

ID Rule Severity
IN1 Roadmaps follow roadmap-{product}.md info

Instance Roadmap (IR)

Conventions documented in shared/conventions.md §Roadmaps.

ID Rule Severity
IR1 Roadmap has # Roadmap header warn
IR2 Roadmap declares an Owner warn
IR3 Version sections have metadata comment info
IR4 Items have a status tag warn
IR5 Items have an @owner warn
IR6 Uses convergence markers info
IR7 Uses cible: markers info
IR8 Uses source: markers info

Artifact types

By default, the audit scans notes and reviews in shared/. An instance can declare additional artifact types in shared/conventions.md using a ## Artifact types section:

## Artifact types

| Type | Directory | Naming | Extra fields |
|------|-----------|--------|--------------|
| notes | shared/notes/ | `note-{subject}-{author}.md` | |
| reviews | shared/review/ | `review-{subject}-{author}.md` | subject |
| features | shared/features/ | `feature-{name}.md` | |
| adr | shared/adr/ | `adr-{number}-{title}.md` | |
| team-orga | shared/orga/ | `team-orga.md` | |

The --artifacts flag lets the user override which types are audited:

# Audit only protocol checks + notes and reviews (default)
python analysis/cli/probe.py /path/to/instance

# Audit with features included
python analysis/cli/probe.py /path/to/instance --artifacts notes,reviews,features

# Protocol checks only — skip all artifact and instance checks
python analysis/cli/probe.py /path/to/instance --protocol-only

When --protocol-only is set, all artifact checks (AN1-AN5, AR1-AR5, AF1-AF3) and instance checks (IS1-IS4, IN1, IR1-IR8) are skipped.


Phase 2 — Exchanges & friction

Phase 2 scans all .md files in the declared artifact directories and extracts:

These are observational — no pass/fail, just data.


Conventions

Instance conventions. Extend as the project evolves.

Artifact types

Declare which artifact types this instance uses. The audit checks only declared types.

Type Directory Naming Extra fields
notes shared/notes/ note-{subject}-{author}.md
reviews shared/review/ review-{subject}-{author}.md subject

<!-- Add rows for additional types used by this instance, e.g.:

features shared/features/ feature-{name}.md
adr shared/adr/ adr-{number}-{title}.md
team-orga shared/orga/ team-orga.md

-->


Structure

Maintain as you go. When a new directory appears in shared/ (notes/, review/, etc.), add it here so personas know where to look and where to deposit.

instance/
├── sofia.md
├── shared/
│   ├── conventions.md
│   └── orga/
│       ├── personas/
│       └── contextes/
├── {space}/
│   ├── CLAUDE.md
│   └── sessions/
└── ...

Repo ownership (optional)

<!-- Uncomment and fill if your instance spans external repos.

Repo Path Owner
product-repo doc/architecture/ @architect
product-repo (rest) @dev

-->


Sessions

Session summary

At each closure, the persona creates a file in {space}/sessions/:

{YYYY-MM-DD}-{HHmm}-{persona}.md

HHmm is the closure time (not the boot time).

Session frontmatter

---
persona: persona-name
date: YYYY-MM-DD
session: "HHmm"
---

Protocol sections (MUST)

Section Content
## Produced Files created or modified
## Decisions Choices made
## Shared notes Artifacts deposited in shared/
## Open Unresolved questions

No prose — short lists. 30 lines max.

Observational sections

Section Status Content
## Orchestrator friction SHOULD Qualified frictions
## Flow MAY Epistemic contributions

Commits

{persona}: {short summary} ({date})

One commit per session.


Artifacts

Every artifact deposited in shared/ carries a YAML frontmatter.

---
from: emitting-persona
to: recipient-persona
nature: signal           # signal | question | request | response
status: new              # new | read | done
date: YYYY-MM-DD
ref: source-artifact     # SHOULD when nature = response (filename without extension)
---

Lifecycle

Status Meaning
new Deposited, not yet read by recipient
read Read by recipient
done Processed by recipient

Resolution

When an artifact is processed, each point SHOULD carry a resolution tag in the document body:

→ ratified | → contested | → revised | → rejected


Friction

Each line carries: marker + description + initiative + resolution.

- [marker] description — [initiative] → resolution

Markers

5 epistemic positions. Closed set — do not add new ones.

Symbol Marker Meaning
[sound] Corroboration — position is correct
~ [contestable] Underdetermination — defensible but not the only reading
[simplification] Reductionism — reality is more complex
[blind_spot] Incompleteness — missing data
[refuted] Refutation — factually incorrect or incoherent

Bracketed keywords are authoritative for the audit.

Initiative

[persona] or [PO] — who initiated the friction topic.

Resolution

Tag Meaning
ratified Agreement — the position is accepted
contested Disagreement maintained — no change of position
revised Disagreement with change of position
rejected Terminal disagreement — the position is discarded

One tag per friction point.

Cross-session mutability

A resolution may evolve in a later session. The friction SHOULD carry a ref: field pointing to the original friction:

- ✓ [sound] description — [persona] → ratified (ref: 2026-04-10-1430-persona/3)

Quick reading


Contribution (epistemic flow)

Section ## Flow — optional.

- {direction}:{type} — description
Direction Meaning
H The human (orchestrator) contributes
A The assistant (persona) contributes
Type Definition
substance New information
structure Formatting, categorization, synthesis
contestation Challenge, counter-example
decision Arbitration, choice made

Optional counting at end of section.


Roadmaps

Roadmaps live in shared/ and follow the naming convention roadmap-{product}.md.

Structure

Each roadmap SHOULD have:

Items

Each item is a markdown list entry (- [status] description @owner).


Cross-instance exchanges

When the orchestrator routes an artifact between two instances, the artifact MUST be deposited in shared/ of the recipient's instance — not the emitter's.

The emitting persona does not need to know the recipient's instance. The orchestrator crosses instance boundaries — personas remain isolated.

See protocol/exchange.md §Cross-instance exchanges.