diff --git a/.eamos-core/docs/cli.md b/.eamos-core/docs/cli.md new file mode 100644 index 0000000..90c6842 --- /dev/null +++ b/.eamos-core/docs/cli.md @@ -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 [--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 +``` + +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 +``` + +| 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 --store STORE.json +python tools/series.py open --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 [--minutes N] [--template discovery-decision] +python tools/facilitate.py followup --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 --repo REPO.json [--date 2026-06] +python tools/advisor.py match --repo REPO.json [--top 3] +python tools/advisor.py simulate --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 [--out PATH] # Markdown (deterministic) +python tools/emit_svg.py [--out PATH] # SVG (deterministic) +python tools/emit_pptx.py --out deck.pptx # needs python-pptx +python tools/emit_docx.py --out pre-read.docx # needs python-docx +python tools/emit_xlsx.py --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. diff --git a/README.md b/README.md index fec914f..7335e8d 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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