Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Practitioner Operations Framework

A generic operational methodology for programme managers, grants officers, and institutional coordinators who manage portfolios of projects under pressure. Seven-loop architecture, deterministic-first processing, maker-checker quality gates, and structured state management.

This framework is the distilled methodology behind the domain-specific toolkits (afd-grant-monitoring, erasmus-programme-toolkit, horizon-europe-consortium-ops).

The core idea

Every operational role in programme management involves the same seven categories of work, regardless of the funding instrument or sector. This framework names them, structures them as automation loops, and provides the scaffolding to implement them in any context.

The seven loops

Loop Category What it does
1. Pre-Read Report review Parse incoming reports into structured briefs before bilateral meetings
2. Dashboard Portfolio monitoring Refresh portfolio status indicators from source data
3. Response Reactive processing Draft responses to requests (amendments, queries, approvals)
4. Preparation Visit/meeting prep Assemble document packs for field visits or steering committees
5. Briefing Upward reporting Compile portfolio briefs for governance bodies
6. Triage Query management Classify and draft responses to inbound communications
7. Digest Weekly synthesis Compile all outputs into a single operational summary

Architecture

loops/
  base_loop.py                # Abstract base class for all loops
  loop_runner.py              # Loop execution engine with state management
  trace_emitter.py            # Execution telemetry

patterns/
  maker_checker.py            # LLM maker-checker pattern implementation
  rag_engine.py               # Generic RAG (Red/Amber/Green) computation engine
  variance_detector.py        # Variance detection across structured datasets
  document_parser.py          # Multi-format document parser (Excel, Word, PDF)
  report_generator.py         # Structured report generation (Markdown, Word, Excel)

docs/
  methodology.md              # The operational methodology in full
  loop_pattern.md             # How to design and implement a new loop
  rag_design.md               # Designing RAG systems for different contexts
  maker_checker.md            # The maker-checker pattern for LLM quality assurance
  state_management.md         # State file design and audit trail
  telemetry.md                # Execution telemetry and performance analysis

examples/
  config.yaml                 # Generic configuration template
  new_loop_template.py        # Skeleton for implementing a new domain-specific loop

Design principles

1. Deterministic first, LLM second

Computation (RAG, variance, aggregation) is deterministic. LLM synthesis is optional and used only for narrative commentary. The system must produce correct outputs with --no-llm before any LLM features are enabled.

2. Human accountability

Loops produce drafts. Humans review and send. No automated transmission to external parties. The practitioner is always the accountable party.

3. Structured I/O

Inputs and outputs follow defined schemas. Loops are parsers and transformers, not generators. This constrains the problem space and minimises the risk of hallucination when LLM synthesis is used.

4. Maker-checker quality gate

When LLM synthesis is enabled, a maker model produces the output and a checker model verifies it against source data. If the checker raises concerns, the loop halts. No unchecked LLM output reaches a stakeholder.

5. State as audit trail

Every loop run is recorded in a state file with inputs processed, outputs produced, and decisions made. State files are append-only and provide a complete audit trail of portfolio management decisions.

6. Portable across domains

The seven-loop pattern applies to any structured portfolio management context. Domain-specific logic (schemas, thresholds, terminology) is injected via configuration and subclass overrides.

Quick start: implementing a new loop

from loops.base_loop import BaseLoop

class MyLoop(BaseLoop):
    loop_id = "my_domain_loop1"

    def ingest(self, inbox_path):
        # Parse your domain-specific inputs
        return parsed_data

    def compute(self, data, config):
        # Deterministic processing
        return computed_results

    def synthesize(self, results, use_llm=False):
        # Optional LLM narrative
        return synthesis

    def output(self, synthesis, outbox_path):
        # Write structured outputs
        return output_paths

See examples/new_loop_template.py and docs/loop_pattern.md for the full pattern.

Applicable contexts

  • Grant portfolio management (any funding instrument)
  • Multi-partner consortium coordination
  • Programme monitoring and evaluation
  • Institutional reporting and compliance
  • Any operational role managing a portfolio of structured projects

Requirements

  • Python 3.10+
  • openpyxl, python-docx, PyYAML
  • pypdf (optional)
  • anthropic (optional, for LLM synthesis)

Author

David Dabert — Fifteen years of programme coordination across EU-funded governance, development, and institutional strengthening programmes. This framework is the distilled operational methodology from managing portfolios across Erasmus+, DFID/UKAID, AFD, and Horizon Europe contexts.

License

MIT

About

Reusable patterns for operational loops: BaseLoop lifecycle, RAG engine, variance detector, maker-checker LLM QA

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages