Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .eamos-core/docs/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# CLI reference

Every tool is **stdlib Python** — no install step. Run from `.eamos-core/` so the relative paths
in the examples resolve. All tools force UTF-8 stdio (safe to pipe on Windows), refuse a missing
input file with one actionable line, and validate the IR contract version before emitting (#62).
The optional binary hops need `pip install python-pptx` / `python-docx` / `openpyxl`.

The pipeline in one line:

```
intake.py → (manifest, by hand + confirm) → render.py → eamos_lint.py → emit_*.py
↑ series.py open facilitate.py / advisor.py
```

## `render.py` — manifest → IR

```
python tools/render.py <manifest.yaml> [--ir deck|infographic|data|mindmap|quiz|topology]
[--out PATH] [--altitude A] [--function F] [--redact]
```

| Flag | Meaning |
|---|---|
| `--ir` | which IR projection to emit (default `deck`); all six project the **same** ledger |
| `--out` | output path for the IR JSON (default: stdout) |
| `--altitude` | override the manifest's `audience_altitude` (render one manifest at several altitudes) |
| `--function` | override the manifest's function pack |
| `--redact` | egress redaction: mask `pii`/`phi`/`sensitive` cells per the confidentiality policy |

## `eamos_lint.py` — the gates

```
python tools/eamos_lint.py <manifest.yaml>
```

Composes the deck-IR and runs every gate (manifest-schema, completeness, grounding-labeled,
audience-fit, deliverable-params, no-action-considered, classification/questions/topology/labels
validity, rubric, confidentiality). Exit 0 = all green; exit 1 lists each failure as
`[gate] message`.

## `intake.py` — sources → typed inputs ledger

```
python tools/intake.py [--csv FILE]... [--series STORE.json] [--deck FILE.pptx]... [--out PATH]
python tools/intake.py --questions <manifest.yaml>
```

| Flag | Meaning |
|---|---|
| `--csv` | a pasted/exported KPI table (repeatable) |
| `--series` | a series store JSON — the prior instance gap-fills |
| `--deck` | an uploaded `.pptx` to extract KPIs from (needs python-pptx; repeatable) |
| `--out` | where to write the YAML `inputs:` fragment (default: stdout) |
| `--questions` | Phase C: print the adaptive question set for a classified manifest |

Precedence on merge (later wins): series → deck → csv. Every emitted cell is
`provenance: sourced`; assumed cells are added later, by hand.

## `series.py` — the persistent series store (the moat)

```
python tools/series.py close <manifest.yaml> --store STORE.json
python tools/series.py open <manifest.yaml> --store STORE.json [--out DIGEST.json]
```

`close` writes an instance's decisions / open actions / rolling risks / KPI history into the
store (idempotent: re-closing the same instance replaces, never duplicates). `open` prints the
carry-forward digest the next instance pre-reads.

## `facilitate.py` — the regie

```
python tools/facilitate.py prep <manifest.yaml> [--minutes N] [--template discovery-decision]
python tools/facilitate.py followup <manifest.yaml> --outcomes OUTCOMES.yaml [--store STORE.json] [--out MINUTES.md]
```

`prep` prints a timeboxed agenda + per-section facilitation script (attendee roster / RACI if the
manifest carries one). `followup` turns **human-captured** outcomes into minutes and carries them
into the series store — the agent never invents the room's outcomes.

## `advisor.py` — precedents & what-if

```
python tools/advisor.py record <manifest.yaml> --repo REPO.json [--date 2026-06]
python tools/advisor.py match <manifest.yaml> --repo REPO.json [--top 3]
python tools/advisor.py simulate <manifest.yaml> --set w.tco=0.3 [--set key=value]...
```

`record` files a closed decision (replace-by-instance). `match` ranks past cases by
classification similarity. `simulate` re-weights a scorecard and reports whether the winner flips.

## Emitters — IR → deliverable (the cosmetic last hop)

```
python tools/emit_md.py <deck-ir.json|quiz-ir.json> [--out PATH] # Markdown (deterministic)
python tools/emit_svg.py <info|mindmap|topology-ir.json> [--out PATH] # SVG (deterministic)
python tools/emit_pptx.py <deck-ir.json> --out deck.pptx # needs python-pptx
python tools/emit_docx.py <deck-ir.json> --out pre-read.docx # needs python-docx
python tools/emit_xlsx.py <data-ir.json> --out kpis.xlsx # needs openpyxl
```

Each emitter checks `ir_version` and refuses a stale artifact ("re-render the manifest"). Colors
and typography come from the theme tokens (`orchestrator/os/themes/`); the amber to-verify color
is reserved and identical across themes.

## `check_docs.py` — the doc-path gate

```
python tools/check_docs.py
```

Fails listing every path referenced by `AGENTS.md` / `README.md` / `CLAUDE.md` that does not
exist in the tree (#65). Runs in CI.
82 changes: 76 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,76 @@ A small composable grammar (RFC §3), not a catalogue of meeting types:

A QBR is not a type — it is `review @ c-level × finance × {context}`. The render path is
**deterministic**: the meeting manifest renders into a typed **deck-IR**, gates run on the IR, and
the `pptx`/`docx`/`xlsx` skills are only the cosmetic last hop (RFC §5).
the `pptx`/`docx`/`xlsx` skills are only the cosmetic last hop (RFC §5). How context flows through
that path, station by station: [the context engine](#the-context-engine). Every tool and flag:
[the CLI reference](.eamos-core/docs/cli.md).

## The context engine

EAMOS never passes your meeting context through a prompt — it **compiles** it. Context moves
through four typed stations, and each hop is validated by a gate:

1. **The inputs ledger** (`inputs:` in the manifest) — every number and fact you provide is a
typed cell with `label`, `value`, `source`, and `provenance: sourced | assumed`. Prose never
contains a number; it binds a cell with `{{key}}`. `tools/intake.py` builds this ledger from
pasted CSVs, a prior instance's series store, or an uploaded deck — zero hand-entry.
2. **The meeting manifest** — the ledger plus the four axes (archetype × altitude × function ×
company context) and the authored content. One file, one source of truth, validated against a
schema (`manifest-schema`) and confirmed by a human before anything renders
(`manifest-confirmed`).
3. **The IR** (`tools/render.py`) — a deterministic, versioned JSON projection per deliverable
(deck, infographic, KPI table, mind map, quiz, topology) over the *same* ledger, so a number
cannot diverge between the deck and the one-pager. Sourced values render plain; anything else
renders labeled `⟨… — to verify⟩` (fail-closed) and is collected into a review appendix.
4. **The gates** (`tools/eamos_lint.py`) — structural checks on the IR and the manifest
(completeness, labeled grounding, audience fit, confidentiality, …). Only a green IR reaches
the cosmetic last hop (the `emit_*.py` tools — Markdown, PPTX, DOCX, SVG, XLSX — themed by
data tokens).

Same manifest in, same bytes out — the CI proves it on every push, on Linux and Windows.

### Sourced vs assumed, visibly

One cell of the reference manifest is missing real material, so it is marked `assumed`:

```yaml
kpi.churn_q3:
value: "~4.2%"
provenance: assumed # missing material, filled professionally — never silently
assumption: "stimato dal trend H1; placeholder — adattare e verificare prima della sala"
review_required: true
```

Every deliverable renders it **labeled, never plain** — this line is from the rendered deck:

```text
- **Churn logo Q3**: ⟨~4.2% — da verificare⟩
```

The `⟨…⟩` marker survives into the deck, the pre-read, the infographic (amber), the sheet
(highlighted), and the "verify before the room" appendix — and the `grounding-labeled` gate turns
red if a label or an appendix entry is missing. A typo'd provenance is treated as assumed
(fail-closed), so a value is plain only when it is *explicitly* sourced.

## Try it in 60 seconds

From a clone (the repo is private until GTM — see the installer note below for the bundle path):

```sh
git clone https://github.com/danielPoloWork/pgs-eamos.git
cd pgs-eamos/.eamos-core

python tools/render.py orchestrator/examples/qbr-c-level.yaml --out build/deck-ir.json
python tools/eamos_lint.py orchestrator/examples/qbr-c-level.yaml
python tools/emit_md.py build/deck-ir.json --out build/deck.md
python tools/facilitate.py prep orchestrator/examples/qbr-c-level.yaml --minutes 60
```

That renders the reference QBR into a gated deck-IR, lints it (all gates green), emits the
Markdown deck, and prints a timeboxed facilitation script. **No dependencies — stdlib Python**
(3.12+). `pip install python-pptx` only if you want the `.pptx` hop
(`python tools/emit_pptx.py build/deck-ir.json --out build/deck.pptx`). The full tool-by-tool
reference: [`.eamos-core/docs/cli.md`](.eamos-core/docs/cli.md).

## The moat

Expand Down Expand Up @@ -79,11 +148,12 @@ overwrites). Double-click `setup.command` (macOS) or `setup.bat` (Windows).

## Status

Early. The design of record is [RFC-0001](.eamos-core/docs/rfc/0001-eamos-meeting-os.md) and
[RFC-0002](.eamos-core/docs/rfc/0002-deliverable-catalogue-and-ir-families.md); the plan is
[ROADMAP.md](ROADMAP.md). **M1** (the QBR @ C-level reference) renders end-to-end and
deterministically — manifest → deck-IR → Markdown deck + `.pptx` board deck, gates green;
**M2** (the composable archetype grammar) is in progress.
Pre-1.0, feature-complete through **M8**: the whole loop — manifest → IR → gates → deck,
pre-read, infographic, KPI sheet, quiz, topology — renders end-to-end and deterministically, with
the series store, intake, facilitation, the advisor, and the guided installer shipped. The design
of record is [RFC-0001](.eamos-core/docs/rfc/0001-eamos-meeting-os.md) and
[RFC-0002](.eamos-core/docs/rfc/0002-deliverable-catalogue-and-ir-families.md); the plan and the
milestone log are in [ROADMAP.md](ROADMAP.md).

## Repository

Expand Down
Loading