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
10 changes: 10 additions & 0 deletions .eamos-core/docs/rfc/0001-eamos-meeting-os.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ draft/approve/own what), and the invariant *humans hold every terminal gate*.
- **Persona** — specialized agents under `agent/*.md`: `exec-briefer`, `facilitator`,
`risk-analyst`, `rca-lead`, `retro-coach`, `discovery-researcher`, `minute-taker`, plus the
meeting architect.

> **Erratum (2026-07, #65).** As built, the `agent/*.md` persona files have not shipped: the
> meeting-architect persona lives in `AGENTS.md`, and the specialized personas are tracked in the
> ROADMAP backlog. The persona ≠ authority separation and the non-delegable gates hold as designed.
- **Authority** — a path→role ownership map over deliverables, and an escalation ladder
`facilitator → meeting-owner → human`. The non-delegable gates: `manifest-confirmed`,
`human-runs-the-room`. The agent **never sends material to real executives** and **never runs a
Expand Down Expand Up @@ -262,6 +266,12 @@ archetype × altitude) is data too, mirroring EADOS's `eval/rubric.md`. Initial
shaping respected: slide budget, jargon level, lead-with), `completeness` (every archetype-
required section present), `review-passed`, `human-runs-the-room`, `series-updated`.

> **Erratum (2026-07, #65).** As built, there is no `orchestrator/os/gate/` directory: the gates
> are code in `tools/eamos_lint.py` (validated by `tools/tests/`), while their **vocabularies**
> are data under `orchestrator/os/` — the manifest schema, the intake taxonomy, the deliverable
> registries, the chrome labels, the themes. "Gates as data" is tracked in the ROADMAP backlog.
> The rubric is data as designed (`eval/rubric.yaml`).

## 11. Enterprise lens (confidentiality & regulatory)

Meeting material is among the most sensitive enterprise data: board financials, comp/layoffs (HR),
Expand Down
110 changes: 110 additions & 0 deletions .eamos-core/tools/check_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env python3
"""Doc-path check (#65): every repo path the top-level docs reference must exist in the tree.

For an agent-first repo the contract is load-bearing documentation — an agent told to load a
persona from a directory that does not exist will fail or, worse, improvise one. This is the doc
equivalent of the gates the repo already believes in: extract every path-looking reference from
AGENTS.md / README.md / CLAUDE.md (markdown link targets, inline-code paths, and AGENTS.md's §4
layout tree) and fail loudly, listing each broken reference.

python .eamos-core/tools/check_docs.py

A prose path may be written relative to the repo root or to `.eamos-core/` (both are natural in
context); a `*` glob must match at least one file. `build/` outputs are transient by design and
skipped.
"""

import glob as globmod
import os
import re
import sys

TOOLS = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, TOOLS)
import _cli # noqa: E402 (utf8_stdio, #54)

ROOT = os.path.dirname(os.path.dirname(TOOLS))
DOCS = ("AGENTS.md", "README.md", "CLAUDE.md")
BASES = ("", ".eamos-core")
LINK_RE = re.compile(r"\]\(([^)#?\s]+)\)")
CODE_RE = re.compile(r"`([^`\s]+)`")
TREE_RE = re.compile(r"^([│ ]*)(?:├──|└──)\s+(\S+)")


def _exists(path):
for base in BASES:
candidate = os.path.join(ROOT, base, path)
if "*" in path:
if globmod.glob(candidate):
return True
elif os.path.exists(candidate):
return True
return False


def _link_paths(text):
return [m.group(1) for m in LINK_RE.finditer(text)
if not m.group(1).startswith(("http://", "https://", "mailto:"))]


def _code_paths(text):
"""Inline-code spans that look like repo paths: contain a '/', no placeholders/options."""
out = []
for m in CODE_RE.finditer(text):
tok = m.group(1)
if "/" not in tok or tok.startswith(("http", "--", "#", "build/")):
continue
if any(c in tok for c in "<>{}$()«⟨"): # placeholders / prose, not paths
continue
out.append(tok.rstrip("/").rstrip(".,;:"))
return out


def _expand_braces(name):
m = re.match(r"(.*)\{([^}]*)\}(.*)", name)
return [f"{m.group(1)}{x}{m.group(3)}" for x in m.group(2).split(",")] if m else [name]


def _tree_paths(text):
"""Paths from AGENTS.md's fenced layout tree: depth = marker column / 4."""
paths, stack, in_tree = [], [], False
for line in text.split("\n"):
if not in_tree and line.strip() == "```text":
in_tree = True
continue
if in_tree and line.strip() == "```":
break
m = TREE_RE.match(line) if in_tree else None
if not m:
continue
depth = len(m.group(1)) // 4
stack = stack[:depth]
for name in _expand_braces(m.group(2)):
paths.append("/".join(stack + [name.rstrip("/")]))
stack.append(m.group(2).rstrip("/"))
return paths


def main():
_cli.utf8_stdio() # Windows: piped stdout must stay UTF-8 (#54)
broken = []
for doc in DOCS:
text = open(os.path.join(ROOT, doc), encoding="utf-8").read()
refs = _link_paths(text) + _code_paths(text)
if doc == "AGENTS.md":
refs += _tree_paths(text)
for ref in refs:
if not _exists(ref):
broken.append(f"{doc}: '{ref}' does not exist in the tree")
if broken:
print("check_docs: FAIL — the docs reference paths that do not exist (#65)\n")
for b in broken:
print(f" {b}")
print(f"\n{len(broken)} broken reference(s).")
return 1
print("check_docs: OK — every doc-referenced path resolves")
return 0


if __name__ == "__main__":
sys.exit(main())
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
- name: Compile every tool
run: python -m py_compile .eamos-core/tools/*.py

- name: Doc-path check (top-level docs reference only real paths, #65)
run: python .eamos-core/tools/check_docs.py

- name: Unit tests (loader, render, gates, flows)
run: python -m unittest discover -s .eamos-core/tools/tests -p "test_*.py"

Expand Down
35 changes: 19 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ The master design is [RFC-0001](.eamos-core/docs/rfc/0001-eamos-meeting-os.md);
## 1. Persona

You are an **Enterprise Project Architect / agentic-OS engineer** (20+ yrs). Two hats: maintain
the factory (archetypes, deck-IR, templates, gates, lint) and, on request, prepare the material
and the regie for one meeting. Specialized meeting personas live in `.eamos-core/agent/*.md`
(`exec-briefer`, `facilitator`, `risk-analyst`, `rca-lead`, `retro-coach`, `discovery-researcher`,
`minute-taker`).
the factory (archetypes, deck-IR, emitters, gates, lint) and, on request, prepare the material
and the regie for one meeting. Specialized meeting personas (exec-briefer, facilitator,
risk-analyst, rca-lead, retro-coach, discovery-researcher, minute-taker) are **planned, not yet
shipped** — tracked in the [ROADMAP backlog](ROADMAP.md); until they land, this file is the only
persona (see the RFC-0001 §8 erratum).

## 2. Language (three tiers — RFC §7)

Expand Down Expand Up @@ -42,27 +43,29 @@ Its genericity is factored into data layers (RFC §3):
- **Meeting manifest** — `orchestrator/examples/*.yaml` shape: the maintainer's answers + the typed
inputs ledger, one source of truth.
- **Deck-IR** — the deterministic intermediate representation that gates run on (RFC §5).
- **Templates** — deliverable templates the deck-IR renders into (`.pptx`/`.docx`/`.md`).
- **Emitters** — the cosmetic IR → file hop (`tools/emit_md.py` and friends: Markdown, PPTX, DOCX,
SVG, XLSX), themed by the token files in `orchestrator/os/themes/`. There is no templates
directory: a deliverable's form comes from the IR plus data (registry params + theme tokens).

## 4. Repository Layout

```text
.
├── AGENTS.md # this file — governs work ON EAMOS
├── CLAUDE.md / GEMINI.md # tool adaptersdefer here
├── CLAUDE.md # tool adapterdefers here
├── README.md # what EAMOS is and how it works
├── ROADMAP.md # the plan (covers RFC-0001)
└── .eamos-core/ # ALL factory machinery — one ignorable folder
├── agent/ # the meeting architect + specialized personas
├── orchestrator/ # the engine: interview, archetypes, deck-ir, render
│ ├── archetypes/ # the ~8 archetype profiles (data)
│ ├── os/ # machine-readable specs: workflow, authority, deck-ir, gate
│ ├── commands/ # phase commands: intake, structure, draft, review, facilitate, follow-up
├── setup/ # guided installer (M8): POSIX / macOS / PowerShell / cmd
└── .eamos-core/ # ALL factory machinery — one ignorable folder
├── orchestrator/ # the engine: archetypes, overlays, intake, machine specs
│ ├── archetypes/ # the archetype profiles (data)
│ ├── functions/ # function packs (axis 3, data)
│ ├── os/ # machine-readable specs: manifest, deck-ir, deliverables,
│ │ # intake, series, localization, themes, confidentiality, …
│ └── examples/ # reference meeting manifests (e.g. qbr-c-level.yaml)
├── templates/ # deliverable templates (the output)
├── tools/ # eamos_lint.py (self-lint), render.py, emit_*.py
├── eval/ # per-archetype×altitude rubric
└── docs/{rfc,adr}/ # the design of record
├── tools/ # eamos_lint.py (self-lint), render.py, emit_*.py, series.py, …
├── eval/ # per-archetype×altitude rubric (rubric.yaml)
└── docs/{rfc,adr,i18n}/ # the design of record
```

The dot-prefix means a consumer ignores the whole factory with one `.eamos-core/` line.
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file is auto-loaded by **Claude Code**. The full agent contract for working
## TL;DR (do not skip — read AGENTS.md anyway)

- **You are an Enterprise Project Architect / agentic-OS engineer** (20+ yrs). Two hats: maintain
the factory (archetypes, deck-IR, templates, gates, lint) and, on request, prepare the material
the factory (archetypes, deck-IR, emitters, gates, lint) and, on request, prepare the material
and the regie for one meeting.
- **EAMOS is the second instance of the EADOS pattern.** Same machine (interview → manifest →
profiles → templates → render → gate → roles), different output (meeting material, not repos).
Expand Down
2 changes: 2 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ projections), **not** RAG-synthesis over arbitrary sources.
- [ ] Function packs **archetype-aware** — a pack's `add_sections` should only land in relevant archetypes (today they apply to all; worked around in the references)
- [ ] More rubric cells (every archetype × altitude); apply the per-region localization norms
- [ ] More reference meetings (a non-QBR flagship); `tools/tests/` coverage as features land
- [ ] Specialized meeting personas (`agent/*.md`, RFC-0001 §8) + phase commands — referenced by the design, not yet shipped (#65)
- [ ] Gates as data (`orchestrator/os/gate/`, RFC-0001 §10) — today the gates are code in `tools/eamos_lint.py` with their vocabularies as data (#65)

---

Expand Down
Loading