Patterns Orthanc applicables au Cerveau Positronic¶
Sources : ADR-0014 (Task State and Working Memory), ADR-0020 (Human-Workflow Interaction) Date : 2026-02-15 Auteur : Claude (analyse)
Executive Summary¶
Les ADRs d'Orthanc sont une masterclass d'architecture distribuée. Même si ProbatioVault n'adopte pas Orthanc en tant que tel, 5 patterns architecturaux majeurs sont directement applicables au Cerveau Positronic :
- Fencing Tokens (résolution split-brain)
- Working Memory Append-Only (audit trail + context coherence)
- State Machine with Validated Transitions (correctness by design)
- Human-Workflow Integration (4 patterns : Authorization, Clarification, Review, Intervention)
- Context Windowing with Priorities (gestion croissance contexte)
Pattern 1 : Fencing Tokens (Split-Brain Resolution) 🔐¶
Principe Orthanc (ADR-0014, Section Fencing Token Model)¶
Problème : Dans un système distribué, une tâche peut être réassignée à un nouvel agent après un timeout réseau. Si l'agent original revient, deux agents pensent être responsables de la même tâche (split-brain).
Solution : Chaque assignation génère un fencing token monotoniquement croissant (PostgreSQL BIGSERIAL). Toute écriture (checkpoint, verdict, etc.) doit inclure le token et est validée via :
UPDATE Task
SET last_checkpoint_step = $step, status = 'checkpointed'
WHERE task_id = $task_id
AND fencing_token = $current_token -- ✅ Garantie atomique
Propriétés : - Un token par assignation : Réassignation → nouveau token via nextval() - Validé à chaque écriture : Base de données rejette les tokens périmés - Monotoniquement croissant : Token supérieur supersède toujours token inférieur
Exemple de résolution split-brain :
1. Agent A exécute task_123 avec token=1000
2. Network partition → Control plane timeout
3. Control plane réassigne task_123 à Agent B avec token=1001
4. Partition guérit → Agent A revient
5. Agent A essaie PersistCheckpoint(token=1000)
→ Rejeté : token actuel = 1001
6. Control plane envoie RevokeAssignment à Agent A
7. Agent A abort, libère ressources
Application ProbatioVault : Workflow Gates¶
Problème actuel : Si le workflow de gouvernance se bloque (ex: ChatGPT timeout pendant Gate 3 review), on relance manuellement. Mais qu'advient-il si : - Review ChatGPT se termine finalement (après timeout) - Nouvelle review déjà lancée - Deux verdicts contradictoires arrivent
Solution proposée : Fencing tokens pour verdicts de gate.
Implémentation¶
1. Génération token (étape de gate) :
# docs/epics/PD-42/WORKFLOW-STATE.md
story_id: PD-42
current_step: 3
gate_status: IN_PROGRESS
gate_token: 1 # ← Nouveau : Fencing token pour Gate 3
gate_started_at: "2026-02-15T10:00:00Z"
2. Verdict de gate avec token :
# docs/epics/PD-42/gate3-verdict-v1.yaml
version: "1.0.0"
gate_type: CONFORMITY_CHECK
story_id: PD-42
gate_token: 1 # ← Doit matcher le token actuel
verdict: GO
score_mean: 8.5
scores:
completeness: 8.5
testability: 8.0
clarity: 9.0
traceability: 8.5
issued_at: "2026-02-15T10:15:00Z"
3. Validation avant application :
# scripts/apply-verdict.py
def apply_verdict(story_id, verdict_file):
workflow_state = load_workflow_state(story_id)
verdict = load_verdict(verdict_file)
# Fencing token validation
if verdict['gate_token'] != workflow_state['gate_token']:
raise ValueError(
f"Verdict token {verdict['gate_token']} does not match "
f"current gate token {workflow_state['gate_token']}. "
f"This verdict is stale (gate was restarted)."
)
# Appliquer verdict
workflow_state['gate_status'] = verdict['verdict']
workflow_state['gate_token'] += 1 # Incrémenter pour prochaine gate
save_workflow_state(story_id, workflow_state)
4. Relance de gate → Nouveau token :
# Relance Gate 3 après timeout
./scripts/gov-step.sh PD-42 3
# WORKFLOW-STATE.md mis à jour :
# gate_token: 2 (incrémenté)
# gate_status: IN_PROGRESS
Bénéfice : Zéro risque de verdicts périmés appliqués. Si Gate 3 v1 se termine après relance, son gate_token: 1 est rejeté car token actuel = 2.
Pattern 2 : Working Memory Append-Only (Audit Trail + Context) 📝¶
Principe Orthanc (ADR-0014, Section Working Memory)¶
Trois objectifs simultanés : 1. Multi-step coherence : Étapes ultérieures référencent sorties des étapes précédentes 2. Crash recovery : Nouvel agent reçoit historique complet et reprend avec contexte 3. Audit trail : Log immutable de tout ce que l'agent a fait et pourquoi
Structure : Append-only log avec 9 types d'entrées (prompt_sent, ai_response, artifact, decision, tool_call, tool_result, child_result, error, status_update).
Invariants : - Jamais de UPDATE/DELETE pendant exécution - Ordonné par step_sequence + created_at - Stockage hybride : Payload inline si petit, blob storage si > seuil
Application ProbatioVault : Artefacts de Workflow¶
Problème actuel : Les artefacts de gouvernance (spec, tests, verdicts, etc.) sont créés mais pas structurés comme un log append-only. Résultat : - Pas de traçabilité complète (ex: quand Gate 3 v2 a-t-il été lancé ?) - Difficile de reconstruire l'historique des décisions - Pas de lien explicite entre artefacts
Solution proposée : Workflow Memory Append-Only (inspiré d'Orthanc).
Implémentation¶
1. Créer fichier de working memory :
# docs/epics/PD-42/workflow-memory.yaml
story_id: PD-42
entries:
- id: "entry-001"
step: 0
type: "need_created"
created_at: "2026-02-15T09:00:00Z"
payload_ref: "PD-42-besoin.md"
- id: "entry-002"
step: 1
type: "specification_created"
created_at: "2026-02-15T09:30:00Z"
payload_ref: "PD-42-specification.md"
agent: "ChatGPT"
- id: "entry-003"
step: 3
type: "gate_review_requested"
created_at: "2026-02-15T10:00:00Z"
payload_ref: "gate3-review-v1.md"
gate_type: "CONFORMITY_CHECK"
gate_token: 1
- id: "entry-004"
step: 3
type: "verdict_issued"
created_at: "2026-02-15T10:15:00Z"
payload_ref: "gate3-verdict-v1.yaml"
verdict: "GO"
score_mean: 8.5
# Jamais de modification des entries précédentes
# Nouvelle entry si nouvel événement
2. Types d'entrées ProbatioVault :
| Type | Description | Payload |
|---|---|---|
need_created | Expression de besoin (étape 0) | Lien vers besoin.md |
specification_created | Spécification (étape 1) | Lien vers specification.md |
tests_created | Tests & validation (étape 2) | Lien vers tests.md |
gate_review_requested | Review de gate lancée | Lien vers review.md |
confrontation_generated | Confrontation produite | Lien vers confrontation.md |
verdict_issued | Verdict de gate | Lien vers verdict.yaml |
correction_applied | Corrections après NON_CONFORME | Détails corrections |
code_contract_defined | Code contract créé (étape 4) | Lien vers code-contracts.yaml |
implementation_started | Début implémentation (étape 6) | Branch feature créée |
agent_task_completed | Tâche agent terminée (6b) | Commit SHA, agent |
acceptability_validated | Reviews acceptabilité (étape 7) | Résultats linter, tests, reviews |
pipeline_monitored | Surveillance pipeline GitLab | Status pipeline |
rex_completed | REX terminé (étape 9) | Lien vers rex.md |
3. Script d'ajout d'entrée :
# scripts/add-workflow-entry.sh
#!/bin/bash
STORY_ID=$1
ENTRY_TYPE=$2
PAYLOAD_REF=$3
# Générer ID unique (UUID v7 comme Orthanc)
ENTRY_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Append entry (YAML)
cat >> docs/epics/${STORY_ID}/workflow-memory.yaml <<EOF
- id: "$ENTRY_ID"
step: $(get_current_step $STORY_ID)
type: "$ENTRY_TYPE"
created_at: "$TIMESTAMP"
payload_ref: "$PAYLOAD_REF"
EOF
echo "✅ Entry $ENTRY_ID added to workflow memory"
4. Intégration workflow :
# Exemple : Après verdict Gate 3
./scripts/gov-step.sh PD-42 3
# Interne : Script génère verdict-v1.yaml
# Puis ajoute entry
./scripts/add-workflow-entry.sh PD-42 "verdict_issued" "gate3-verdict-v1.yaml"
Bénéfices : - ✅ Audit trail complet : Chaque action tracée avec timestamp - ✅ Reconstruction historique : Lire workflow-memory.yaml = comprendre tout le workflow - ✅ Crash recovery : Si workflow interrompu, reprendre du dernier entry - ✅ Traçabilité : Lien entre artefacts explicite
Pattern 3 : State Machine with Validated Transitions ⚙️¶
Principe Orthanc (ADR-0014, Section Task State Machine)¶
8 états + transitions validées + validation à 2 niveaux :
- Application-side check : Scala valide
(current_state, target_state)avant UPDATE - Database CHECK constraint : PostgreSQL rejette valeurs illégales (defense in depth)
Table de transitions : Spécifie exactement quelles transitions sont permises (ex: running → checkpointed OK, running → completed interdit).
Bénéfice : Impossible d'arriver dans un état incohérent (ex: task completed sans être passée par checkpointed).
Application ProbatioVault : State Machine de Workflow¶
Problème actuel : Workflow-State.md est manuel. Aucune validation que les transitions sont légitimes (ex: passer de Step 3 à Step 6 sans passer par Step 4-5).
Solution proposée : State machine de workflow avec transitions validées.
Implémentation¶
1. Définir états et transitions :
# docs/governance/workflow-state-machine.yaml
states:
- step_0: "Expression de besoin"
- step_1: "Spécification"
- step_2: "Tests & Validation"
- step_3: "Review spécification (Gate)"
- step_4: "Plan d'implémentation"
- step_5: "Review plan (Gate)"
- step_6: "Implémentation"
- step_7: "Acceptabilité"
- step_8: "Review acceptabilité (Gate)"
- step_9: "REX"
valid_transitions:
- from: step_0
to: [step_1]
trigger: "Besoin complété"
- from: step_1
to: [step_2]
trigger: "Spécification complétée"
- from: step_2
to: [step_3]
trigger: "Tests définis"
- from: step_3
to: [step_4, step_1] # GO → Step 4, NON_CONFORME → Step 1
trigger: "Verdict Gate 3"
conditions:
- verdict: GO → step_4
- verdict: NON_CONFORME → step_1 # Retour correction spec
- from: step_4
to: [step_5]
trigger: "Plan complété"
- from: step_5
to: [step_6, step_4] # GO → Step 6, NON_CONFORME → Step 4
trigger: "Verdict Gate 5"
- from: step_6
to: [step_7]
trigger: "Implémentation complétée"
- from: step_7
to: [step_8]
trigger: "Acceptabilité validée"
- from: step_8
to: [step_9, step_7] # GO → Step 9, NON_CONFORME → Step 7
trigger: "Verdict Gate 8"
conditions:
- verdict: GO AND pipeline: success → step_9
- verdict: NON_CONFORME → step_7
- from: step_9
to: [] # Terminal
trigger: "REX complété"
2. Script de validation de transition :
# scripts/validate-transition.py
import yaml
def validate_transition(story_id, target_step):
# Charger state machine
with open('docs/governance/workflow-state-machine.yaml') as f:
sm = yaml.safe_load(f)
# Charger état actuel
with open(f'docs/epics/{story_id}/WORKFLOW-STATE.md') as f:
current_step = parse_current_step(f.read())
# Vérifier transition valide
valid = any(
t['from'] == f'step_{current_step}' and f'step_{target_step}' in t['to']
for t in sm['valid_transitions']
)
if not valid:
raise ValueError(
f"Invalid transition: step_{current_step} → step_{target_step}. "
f"This transition is not allowed by the state machine."
)
return True
# Usage
validate_transition('PD-42', 6) # ✅ OK si current_step=5 avec verdict GO
validate_transition('PD-42', 6) # ❌ Erreur si current_step=3 (saute 4-5)
3. Intégration dans gov-step.sh :
# scripts/gov-step.sh (extrait)
STORY_ID=$1
TARGET_STEP=$2
# Validation transition AVANT exécution
python3 scripts/validate-transition.py "$STORY_ID" "$TARGET_STEP"
if [ $? -ne 0 ]; then
echo "❌ Transition invalide. Vérifiez WORKFLOW-STATE.md"
exit 1
fi
# Exécuter étape seulement si validation OK
...
Bénéfice : Impossible de sauter des étapes ou de faire des transitions illégitimes. La state machine garantit la correction du workflow.
Pattern 4 : Human-Workflow Integration (4 Patterns) 🧑💼¶
Principe Orthanc (ADR-0020, Full ADR)¶
4 patterns d'interaction humain-workflow :
- Authorization : Agent demande permission avant action (ex: merge protected branch)
- Clarification : Agent pose questions structurées (ex: OAuth2 ou JWT ?)
- Review : Agent soumet deliverable pour validation humaine (ex: ADR, spec critique)
- Intervention : Humain injecte guidance corrective dans workflow en cours
Chaque pattern : - ✅ Persiste dans PostgreSQL (survit aux crashes) - ✅ Lifecycle à 5 états (PENDING → ACKNOWLEDGED → RESOLVED / ESCALATED → EXPIRED) - ✅ Escalation chains avec timeouts - ✅ Fencing token validation sur réponses - ✅ Audit trail immutable (InteractionAuditEntry)
Application ProbatioVault : Gates PMO + Human Oversight¶
Problème actuel : Gates PMO sont automatiques (Claude orchestrate, ChatGPT review, scoring). Mais certaines stories critiques nécessitent approbation humaine explicite (ex: changements auth, migrations DB).
Solution proposée : Pattern Authorization + Review pour gates critiques.
Implémentation Pattern 1 : Authorization (Gate Critique)¶
Use case : Story PD-XX modifie l'authentification → Gate 8 nécessite approbation humaine en plus des reviews automatiques.
1. Configuration authorization policy :
# docs/governance/authorization-policy.yaml
project_id: ProbatioVault-backend
rules:
- rule_id: "auth-changes-require-approval"
priority: 1
operation_pattern: "gate_8:auth_module" # Gate 8 sur modules auth
interaction_type: AUTHORIZATION
approver:
type: escalation_chain
chain_id: "security-approvers"
timeout_action: ESCALATE
timeout_seconds: 86400 # 24h
- rule_id: "db-migrations-require-approval"
priority: 2
operation_pattern: "gate_8:db_migration"
interaction_type: AUTHORIZATION
approver:
type: user
user_id: "loic@phydya.com"
timeout_action: SUSPEND
timeout_seconds: 172800 # 48h
2. Escalation chain :
# docs/governance/escalation-chains.yaml
- chain_id: "security-approvers"
name: "Security Review Chain"
levels:
- level: 0
approvers:
- type: user
user_id: "security-lead@probatiovault.com"
timeout_seconds: 86400 # 24h
- level: 1 # Escalation si level 0 timeout
approvers:
- type: group
group_id: "architects"
timeout_seconds: 43200 # 12h
- level: 2 # Escalation finale
approvers:
- type: user
user_id: "cto@probatiovault.com"
timeout_seconds: 86400 # 24h
exhausted_action: EXPIRE # Si tous niveaux timeout → EXPIRE
acknowledge_resets_timer: true
3. Workflow avec authorization gate :
# docs/epics/PD-XX/authorization-request.yaml
request_id: "auth-req-001"
story_id: PD-XX
step: 8 # Gate 8
interaction_type: AUTHORIZATION
operation_type: "gate_8:auth_module"
gate_token: 3
context:
description: |
Gate 8 pour story PD-XX (Ajout MFA 2FA).
Modifications critiques dans AuthService, UserRepository.
Reviews automatiques OK (linter, tests, coverage).
Approbation humaine requise avant merge.
impact: |
- APPROVE → Merge feature branch, lancer REX
- REJECT → Bloquer merge, escalader vers correction
payload_content_type: "application/json"
payload:
files_modified:
- "src/auth/AuthService.ts"
- "src/auth/MfaService.ts"
- "src/repositories/UserRepository.ts"
test_coverage: 87%
linter_warnings: 0
reviews:
- type: "code_review"
verdict: "APPROVE"
reviewer: "ChatGPT"
- type: "security_review"
verdict: "APPROVE"
reviewer: "ChatGPT (adversarial)"
artifact_refs:
- "feature/PD-XX-mfa-settings"
- "docs/epics/PD-XX/acceptability.md"
created_at: "2026-02-15T15:00:00Z"
status: PENDING
current_approver: "security-lead@probatiovault.com"
escalation_level: 0
4. Workflow orchestration :
# scripts/gov-step.sh PD-XX 8
# Après reviews automatiques (linter, tests, reviews LLM)
# Vérifier si authorization requise
python3 scripts/check-authorization-policy.py PD-XX gate_8
# Si policy match → Créer authorization request
python3 scripts/create-authorization-request.py \
--story PD-XX \
--step 8 \
--operation "gate_8:auth_module" \
--context "docs/epics/PD-XX/acceptability.md"
# Notifier approver (email, Slack, WhatsApp via OpenClaw)
python3 scripts/notify-approver.py --request-id "auth-req-001"
# Workflow SUSPEND jusqu'à réponse humaine
echo "⏸️ Workflow suspendu - Approbation requise (auth-req-001)"
5. Réponse humaine :
# docs/epics/PD-XX/authorization-response.yaml
request_id: "auth-req-001"
decision: APPROVE # ou REJECT
responder: "security-lead@probatiovault.com"
reasoning: |
Code reviews OK, tests OK, sécurité OK.
MFA implementation suit les standards TOTP.
Approved for merge.
resolved_at: "2026-02-15T16:30:00Z"
gate_token: 3 # Doit matcher le token de la request
6. Application réponse :
# scripts/apply-authorization-response.py
python3 scripts/apply-authorization-response.py \
--request-id "auth-req-001" \
--response "docs/epics/PD-XX/authorization-response.yaml"
# Validation fencing token
# Si APPROVE → Workflow resume (merge, REX)
# Si REJECT → Workflow suspend, escalade correction
Bénéfices : - ✅ Approbation humaine traçable : Audit trail complet - ✅ Escalation automatique : Si security-lead timeout → escalade architects - ✅ Fencing tokens : Zéro risque d'approbation périmée - ✅ Configurable : Policy YAML modifiable sans changer code
Implémentation Pattern 3 : Review (Deliverable Critique)¶
Use case : Spécification critique (étape 1) nécessite review humaine avant Gate 3.
1. Review request :
# docs/epics/PD-XX/review-request-spec.yaml
request_id: "review-req-001"
story_id: PD-XX
step: 1
interaction_type: REVIEW
deliverable_type: "specification"
deliverable_ref: "PD-XX-specification.md"
context:
description: |
Spécification pour feature critique (authentification MFA).
Review humaine requise avant soumission à Gate 3.
artifact_refs:
- "docs/epics/PD-XX/specification.md"
created_at: "2026-02-15T11:00:00Z"
status: PENDING
current_reviewer: "architect-senior@probatiovault.com"
2. Review response :
# docs/epics/PD-XX/review-response-spec.yaml
request_id: "review-req-001"
decision: MODIFY # APPROVE, MODIFY, ou REJECT
feedback:
- section: "3.2 Token Storage"
comment: "Préciser durée de vie du TOTP token (actuellement absent)"
severity: REQUIRED
- section: "4.1 User Flow"
comment: "Ajouter diagramme de séquence pour clarifier flow"
severity: SUGGESTION
responder: "architect-senior@probatiovault.com"
resolved_at: "2026-02-15T12:00:00Z"
3. Modify-Feedback-Resubmit Cycle :
# Workflow reçoit MODIFY verdict
# 1. Incorporer feedback REQUIRED
# 2. Générer spec v2
# 3. Soumettre nouvelle review request (request_id différent, correlation_id identique)
python3 scripts/create-review-request.py \
--story PD-XX \
--deliverable "docs/epics/PD-XX/specification-v2.md" \
--correlation-id "review-req-001" # Lien avec v1
# 4. Reviewer review spec v2
# 5. Si APPROVE → Passer à Gate 3
# 6. Si MODIFY encore → Limité à 3 itérations (config), puis ESCALATE
Bénéfice : Review gates catch issues before commit (exact SC-007 d'Orthanc).
Pattern 5 : Context Windowing with Priorities 📊¶
Principe Orthanc (ADR-0014, Section Context Windowing)¶
Problème : Working memory grandit. Finit par dépasser context window du LLM.
Solution : Context windowing avec règles d'inclusion :
- Toujours inclure : Task definition + 3 dernières entrées
- Summarize older : Entrées au-delà des 3 dernières → Summarization capability
- Priority-based retention : 9 niveaux de priorité (decisions > errors > tool_result > ... > prompt_sent)
- Budget calculation : context_window × 0.7 (30% réservé pour réponse AI)
Bénéfice : Zéro perte de décisions critiques, même sur workflows longs.
Application ProbatioVault : Summarization de Workflow Memory¶
Problème actuel : Workflow memory peut devenir très long (ex: PD-105 avec 13 tâches agents × multiple commits). Si on veut assembler un prompt avec tout l'historique pour une review finale, risque de dépasser context window.
Solution proposée : Context windowing avec priorités pour artefacts de workflow.
Implémentation¶
1. Définir priorités des entry types :
# docs/governance/context-priorities.yaml
# Priorité 1 = Toujours retenu en full, 9 = Summarize en premier
priorities:
1: [verdict_issued, code_contract_defined] # Décisions critiques
2: [correction_applied, pipeline_monitored] # Erreurs et corrections
3: [confrontation_generated, acceptability_validated] # Validations
4: [gate_review_requested, agent_task_completed] # Résultats intermédiaires
5: [specification_created, tests_created, implementation_started] # Créations
6: [need_created, rex_completed] # Contexte initial/final
7: [] # Réservé future
8: [] # Réservé future
9: [] # Réservé future
2. Context windowing script :
# scripts/assemble-context-windowed.py
import yaml
def calculate_size(entry):
"""Estime taille en tokens (1 token ≈ 4 chars)"""
if 'payload_ref' in entry:
content = load_file(entry['payload_ref'])
return len(content) // 4
return 100 # Estimation par défaut
def assemble_context_windowed(story_id, budget_tokens=140000):
# budget_tokens = 200k × 0.7 (30% réservé pour réponse)
# 1. Charger workflow memory
with open(f'docs/epics/{story_id}/workflow-memory.yaml') as f:
memory = yaml.safe_load(f)
entries = memory['entries']
# 2. Toujours inclure : Need + 3 dernières entrées
need_entry = entries[0] # Toujours premier
recent_entries = entries[-3:] # 3 derniers
locked_size = sum(calculate_size(e) for e in [need_entry] + recent_entries)
# 3. Remaining budget
remaining_budget = budget_tokens - locked_size
# 4. Charger priorités
with open('docs/governance/context-priorities.yaml') as f:
priorities = yaml.safe_load(f)
# 5. Trier entries par priorité (sauf need + recent déjà lockés)
middle_entries = entries[1:-3] # Entre need et 3 derniers
def priority_rank(entry):
for rank, types in priorities['priorities'].items():
if entry['type'] in types:
return rank
return 9 # Par défaut : Lowest priority
middle_entries_sorted = sorted(middle_entries, key=priority_rank)
# 6. Retenir tant que budget permet
retained = []
summarize = []
current_size = 0
for entry in middle_entries_sorted:
entry_size = calculate_size(entry)
if current_size + entry_size <= remaining_budget:
retained.append(entry)
current_size += entry_size
else:
summarize.append(entry)
# 7. Summarize via LLM
if summarize:
summary_prompt = "Résume les entrées suivantes en 500 tokens max:\n"
summary_prompt += "\n".join(format_entry(e) for e in summarize)
summary = call_llm_summary(summary_prompt) # Claude ou ChatGPT
summary_entry = {
'id': 'summary-001',
'type': 'context_summary',
'created_at': now(),
'payload': summary
}
else:
summary_entry = None
# 8. Assembler contexte final
final_context = [need_entry]
if summary_entry:
final_context.append(summary_entry)
final_context.extend(retained)
final_context.extend(recent_entries)
return final_context
# Usage
context = assemble_context_windowed('PD-105', budget_tokens=140000)
# Context contient : Need + Summary (si nécessaire) + High-priority entries + 3 recent
3. Intégration dans prompts de gate :
# scripts/assemble-gate-prompt.sh
STORY_ID=$1
GATE_TYPE=$2
# Assembler contexte avec windowing
python3 scripts/assemble-context-windowed.py "$STORY_ID" > /tmp/context.md
# Assembler prompt de gate avec contexte windowé
cat > /tmp/gate-prompt.md <<EOF
# Gate $GATE_TYPE pour $STORY_ID
## Contexte Workflow (Context-Windowed)
$(cat /tmp/context.md)
## Document à Review
$(cat docs/epics/$STORY_ID/specification.md)
## Instructions Review
[...]
EOF
# Envoyer prompt via ChatGPT
cat /tmp/gate-prompt.md | opencode run
Bénéfice : Zéro perte de décisions critiques (verdicts, code contracts), même sur workflows très longs (ex: 50+ entries).
Roadmap d'Adoption 🗓️¶
Q1 2026 : Patterns 1-2 (Foundations) - [ ] Implémenter Fencing Tokens pour verdicts de gate (Pattern 1) - [ ] Créer Workflow Memory Append-Only (Pattern 2) - [ ] Migrer artefacts existants vers workflow-memory.yaml
Q2 2026 : Pattern 3 (Correctness) - [ ] Définir State Machine avec transitions validées (Pattern 3) - [ ] Intégrer validation dans scripts gov-step.sh
Q3 2026 : Patterns 4-5 (Advanced) - [ ] Implémenter Authorization Pattern pour gates critiques (Pattern 4) - [ ] Implémenter Review Pattern pour deliverables critiques (Pattern 4) - [ ] Implémenter Context Windowing pour workflows longs (Pattern 5)
Conclusion 🎯¶
Les ADRs d'Orthanc démontrent qu'une architecture distribuée multi-agents peut être à la fois rigoureuse ET pragmatique. Les 5 patterns extraits sont directement applicables au Cerveau Positronic :
- Fencing Tokens → Résolution split-brain pour verdicts de gate
- Working Memory → Audit trail + traçabilité complète
- State Machine → Correction by design (transitions validées)
- Human-Workflow → Authorization + Review pour gates critiques
- Context Windowing → Gestion workflows longs sans perte décisions
Prochaine étape : POC Fencing Tokens sur une story test (ex: PD-XXX) pour valider le pattern avant déploiement généralisé.