From 7f08bc2aedc62725ef0a5028de78cd2b94490631 Mon Sep 17 00:00:00 2001 From: Memorysaver Date: Sat, 25 Jul 2026 11:08:32 +0800 Subject: [PATCH 01/13] =?UTF-8?q?feat(aep):=20human-alignment=20skill=20v3?= =?UTF-8?q?.3.0=20=E2=80=94=20one-page=20project=20brief=20from=20product-?= =?UTF-8?q?context.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements docs/decisions/human-alignment.md (PR #28, revision 7). The planning layer gets a human-facing surface: one command turns product-context.yaml into a single self-contained HTML page answering where are we, what needs me, and where reality drifted from intent. Proven end-to-end against a real 396-story consumer, whose unedited output ships as the reference example in docs/human-alignment/example-looplia/. Skill (skills/human-alignment/, a fifth marketplace plugin): - derive.mjs — the only legal source of numbers; validates its own output against facts.schema.json before anything reads it - scan-workspace.mjs → arch-rules.mjs → receipt-consumer.mjs — the deterministic architecture pipeline; rules R1–R10 are executable data, and repairs come only from archify's structured receipts within a two-round bound - audit.mjs — the independent mechanical audit; the agent that wrote the prose does not grade it - assemble.mjs — srcdoc-embeds five diagrams into one file, prunes to newest 3 - template.html — the single source of CSS classes AND of the data-fact binding convention, so number provenance is statically checkable Framework specs (skills/product-context/_shared/references/): - attention-set.md — what needs a human, deterministic one-ask order, per-predicate schema tolerance - drift-facts.md — the five drift derivations; hand-authored drift is banned Tooling: - build-skills.sh materializes shared resources into top-level skills, not only product-context children — a standalone skill must carry its own copy because the skills CLI installs one directory at a time. Existing corpus byte-identical. - oxfmt ignores docs/human-alignment/example-*/ — generated artifacts are evidence, not source, and reformatting them would break their content digest. Two derivations corrected by running against real data rather than a fixture: intent-without-evidence derives from the coverage counters (coverage.uncovered is empty precisely when a gate never opened), and its layer scope excludes `ready` as well as `pending` — a dispatchable task is not a started one. Only a `passed` gate yields an unchipped capability; `scripted_passed` appears solely under an EXP chip naming the acceptance run that would settle it. Known gap: evals/skill-routing-observations.json has no entries for the three new routing cases. Those record an independent model's selection against the installed description corpus and cannot be authored by the agent that wrote the description. check-skills-package.sh fails until that probe is run. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01EDTHXC2N5mDL1DtFXopAWn --- .claude-plugin/marketplace.json | 9 +- .oxfmtrc.json | 2 +- CHANGELOG.md | 55 + README.md | 50 +- .../human-alignment/example-looplia/README.md | 59 + .../brief-2026-07-25T0308Z-65e359c6.html | 895 +++ .../example-looplia/code-graph.json | 441 ++ .../example-looplia/facts.json | 4858 +++++++++++++++++ .../example-looplia/manifest.json | 17 + evals/skill-behavior-parity.json | 14 + evals/skill-routing.json | 18 + frontier-fixed.png | Bin 0 -> 121514 bytes scripts/build-skills.sh | 24 +- skills/human-alignment/SKILL.md | 152 + .../assets/aep-loop.workflow.json | 99 + .../assets/story-states.lifecycle.json | 119 + skills/human-alignment/assets/template.html | 853 +++ .../human-alignment/references/.aep-generated | 3 + .../references/attention-set.md | 100 + .../human-alignment/references/checklist.md | 73 + .../human-alignment/references/derivation.md | 69 + .../human-alignment/references/drift-facts.md | 136 + .../human-alignment/references/guideline.md | 120 + .../references/presentation.md | 93 + skills/human-alignment/scripts/arch-rules.mjs | 487 ++ skills/human-alignment/scripts/assemble.mjs | 132 + skills/human-alignment/scripts/audit.mjs | 294 + skills/human-alignment/scripts/derive.mjs | 626 +++ .../human-alignment/scripts/facts.schema.json | 312 ++ .../scripts/receipt-consumer.mjs | 284 + .../scripts/scan-workspace.mjs | 123 + .../autopilot/references/post-merge-guard.md | 6 +- .../autopilot/references/state-schema.md | 6 +- .../gen-eval/references/findings-format.md | 55 +- .../workflow/references/pattern-catalog.md | 13 +- .../_shared/references/attention-set.md | 100 + .../_shared/references/drift-facts.md | 136 + v3f-b1.png | Bin 0 -> 206959 bytes 38 files changed, 10770 insertions(+), 63 deletions(-) create mode 100644 docs/human-alignment/example-looplia/README.md create mode 100644 docs/human-alignment/example-looplia/brief-2026-07-25T0308Z-65e359c6.html create mode 100644 docs/human-alignment/example-looplia/code-graph.json create mode 100644 docs/human-alignment/example-looplia/facts.json create mode 100644 docs/human-alignment/example-looplia/manifest.json create mode 100644 frontier-fixed.png create mode 100644 skills/human-alignment/SKILL.md create mode 100644 skills/human-alignment/assets/aep-loop.workflow.json create mode 100644 skills/human-alignment/assets/story-states.lifecycle.json create mode 100644 skills/human-alignment/assets/template.html create mode 100644 skills/human-alignment/references/.aep-generated create mode 100644 skills/human-alignment/references/attention-set.md create mode 100644 skills/human-alignment/references/checklist.md create mode 100644 skills/human-alignment/references/derivation.md create mode 100644 skills/human-alignment/references/drift-facts.md create mode 100644 skills/human-alignment/references/guideline.md create mode 100644 skills/human-alignment/references/presentation.md create mode 100644 skills/human-alignment/scripts/arch-rules.mjs create mode 100644 skills/human-alignment/scripts/assemble.mjs create mode 100644 skills/human-alignment/scripts/audit.mjs create mode 100644 skills/human-alignment/scripts/derive.mjs create mode 100644 skills/human-alignment/scripts/facts.schema.json create mode 100644 skills/human-alignment/scripts/receipt-consumer.mjs create mode 100644 skills/human-alignment/scripts/scan-workspace.mjs create mode 100644 skills/product-context/_shared/references/attention-set.md create mode 100644 skills/product-context/_shared/references/drift-facts.md create mode 100644 v3f-b1.png diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 58a2235..77e02b6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ "email": "mho@looplia.run" }, "metadata": { - "version": "3.2.1", + "version": "3.3.0", "description": "Skills for product planning, project scaffolding, and agentic development workflows." }, "plugins": [ @@ -49,6 +49,13 @@ "./skills/agentic-development-workflow/git-ref" ] }, + { + "name": "human-alignment", + "description": "Renders product-context.yaml into a one-page HTML project brief: where we are, what needs a human, where reality drifted.", + "source": "./", + "strict": false, + "skills": ["./skills/human-alignment"] + }, { "name": "patterns", "description": "Reusable design patterns: gen/eval, executor abstraction, autopilot orchestration, dynamic workflows, workflow-feedback, design-lens (HCI theory + heuristic health-check).", diff --git a/.oxfmtrc.json b/.oxfmtrc.json index c871730..1a35687 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -1,3 +1,3 @@ { - "ignorePatterns": [] + "ignorePatterns": ["docs/human-alignment/example-*/**"] } diff --git a/CHANGELOG.md b/CHANGELOG.md index f2eaaf5..170c853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,61 @@ bug fixes → **patch**; removing or breaking a skill contract → **major**. > `/envision`, `/dispatch`, `/reflect`, …), which records product-state history > for that project. See [`docs/glossary.md`](docs/glossary.md). +## [3.3.0] - 2026-07-25 + +`/aep-human-alignment` — the planning layer finally has a human-facing surface. +One command turns `product-context.yaml` into a single self-contained HTML page +that answers the three questions a returning human actually has: _where are we, +what needs me, where did reality drift from intent?_ Implemented against +[`docs/decisions/human-alignment.md`](docs/decisions/human-alignment.md) (PR #28, +revision 7) and proven end-to-end on a real 396-story consumer, whose generated +brief ships as the reference example. + +### Added + +- **`skills/human-alignment/`** — a standalone top-level skill (`/aep-human-alignment`), + a fifth marketplace plugin. Seven Node scripts, one template, two archify IRs: + - `derive.mjs` — the only legal source of numbers; validates its own output + against `facts.schema.json` before anything reads it. + - `scan-workspace.mjs` → `arch-rules.mjs` → `receipt-consumer.mjs` — the + deterministic architecture pipeline. The workspace graph is read from the + package manifest, transformed by the auditable rule table R1–R10, and + repaired **only** through archify's own structured receipts, bounded at two + rounds. Same commit in, same artifact out. + - `audit.mjs` — the independent mechanical audit. Evaluator independence: the + agent that wrote the prose does not grade it. + - `assemble.mjs` — embeds every delivered diagram via `srcdoc` into one file, + then prunes to the newest three briefs. +- **Two framework specs** in `skills/product-context/_shared/references/` — + `attention-set.md` ("what needs a human", with a deterministic one-ask order) + and `drift-facts.md` ("where reality drifted", five derivations). Framework + vocabulary with future consumers, not skill-private logic; `/aep-autopilot` + escalation and `/aep-watch` alerting re-point to them in a later release. +- **Reference example** — [`docs/human-alignment/example-looplia/`](docs/human-alignment/example-looplia/): + the unedited brief generated from a real consumer repo, plus its facts JSON, + code graph, and manifest. It lives in `docs/`, not inside the skill, so a + 3.2 MB artifact does not ship with every install. + +### Changed + +- **`scripts/build-skills.sh` materializes shared resources into top-level + skills**, not only `skills/product-context/*`. A standalone skill that reads + `references/attention-set.md` must carry its own copy, because the skills CLI + installs one directory at a time. Existing consumers are unaffected — the + corpus check is byte-identical before and after. + +### Notes + +- Two derivations were corrected before shipping, both surfaced by running + against real data rather than a fixture: intent-without-evidence derives from + the coverage counters (not `coverage.uncovered`, which is empty precisely when + a gate never opened), and its layer scope excludes `ready` as well as + `pending` — a dispatchable task is not a started one. +- Only a `passed` gate yields an unchipped capability. A `scripted_passed` gate + appears solely under an `EXP` chip naming the acceptance run that would settle + it, so the product band cannot claim a sign-off that has not happened. +- Consumers must re-pin to `@v3.3.0` before `/aep-human-alignment` is available. + ## [3.2.1] - 2026-07-18 Patch: the `secret_scan` example in the scaffolded `policy.md` named diff --git a/README.md b/README.md index 6f8ae9d..64debaf 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,7 @@ The `skills` CLI selects by skill name (there's no "group" flag). The groups map | **Product** (product-context) | `aep-envision`, `aep-map`, `aep-model`, `aep-dispatch`, `aep-validate`, `aep-calibrate`, `aep-reflect`, `aep-watch` | | **Setup** (project-setup) | `aep-onboard`, `aep-scaffold`, `aep-e2e-skill-scaffolding` | | **Patterns** (patterns) | `aep-gen-eval`, `aep-executor`, `aep-autopilot`, `aep-workflow`, `aep-workflow-feedback`, `aep-design-lens` | +| **Alignment** (human-alignment) | `aep-human-alignment` | > **Releasing:** bumping `metadata.version` in `.claude-plugin/marketplace.json` must come with a matching [CHANGELOG.md](CHANGELOG.md) entry in the same PR (move the `[Unreleased]` notes under the new `[X.Y.Z] - DATE` heading), and a `vX.Y.Z` git tag on merge to `main`. @@ -626,30 +627,31 @@ Generate a dimension-specific brief, explore or discuss, capture decisions for a ## All Skills -| Skill | Plugin | Purpose | -| ---------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| `/aep-envision` | product-context | Opportunity brief + context document | -| `/aep-map` | product-context | System map + story graph + agent topology | -| `/aep-model` | product-context | Object-first UI structure (OOUX/ORCA Object Map) for UI products | -| `/aep-validate` | product-context | Generator/evaluator validation of any AEP artifact | -| `/aep-dispatch` | product-context | Pick next story + create OpenSpec change | -| `/aep-calibrate` | product-context | Human alignment checkpoint for any quality dimension | -| `/aep-reflect` | product-context | Classify feedback + update context | -| `/aep-watch` | product-context | Ingest telemetry/errors → auto-file stories (self-feeding loop) | -| `/aep-onboard` | project-setup | Verify tools + install plugins | -| `/aep-scaffold` | project-setup | Scaffold monorepo + initialize OpenSpec; idempotent audit→converge for existing projects | -| `/aep-e2e-skill-scaffolding` | project-setup | Generate/upgrade the canonical BDD layer-gate e2e-test skill | -| `/aep-design` | agentic-development-workflow | Explore + propose + review a feature | -| `/aep-launch` | agentic-development-workflow | Spawn workspace (Claude bg subagents/sessions; Codex subagents/exec; tmux when pinned) + optional evaluator | -| `/aep-build` | agentic-development-workflow | Implement → test → PR → merge | -| `/aep-wrap` | agentic-development-workflow | Archive + cleanup + suggest reflect | -| `/aep-git-ref` | agentic-development-workflow | AEP git + worktree conventions (on-demand) | -| `/aep-gen-eval` | patterns | Generator/evaluator separation for honest validation | -| `/aep-executor` | patterns | Host-agnostic backend for spawning/steering workspace agents | -| `/aep-autopilot` | patterns | Autonomous dispatch-launch-monitor-wrap loop via `/loop` | -| `/aep-workflow` | patterns | Dynamic workflows — author a custom multi-agent harness for a task (+ sub-pattern catalog) | -| `/aep-workflow-feedback` | patterns | Capture + review process learnings between downstream projects and AEP | -| `/aep-design-lens` | patterns | Theory-grounded design guideline + heuristic health-check (HCI/design-theory catalog + task/data lens selection) | +| Skill | Plugin | Purpose | +| ---------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `/aep-envision` | product-context | Opportunity brief + context document | +| `/aep-map` | product-context | System map + story graph + agent topology | +| `/aep-model` | product-context | Object-first UI structure (OOUX/ORCA Object Map) for UI products | +| `/aep-validate` | product-context | Generator/evaluator validation of any AEP artifact | +| `/aep-dispatch` | product-context | Pick next story + create OpenSpec change | +| `/aep-calibrate` | product-context | Human alignment checkpoint for any quality dimension | +| `/aep-reflect` | product-context | Classify feedback + update context | +| `/aep-watch` | product-context | Ingest telemetry/errors → auto-file stories (self-feeding loop) | +| `/aep-onboard` | project-setup | Verify tools + install plugins | +| `/aep-scaffold` | project-setup | Scaffold monorepo + initialize OpenSpec; idempotent audit→converge for existing projects | +| `/aep-e2e-skill-scaffolding` | project-setup | Generate/upgrade the canonical BDD layer-gate e2e-test skill | +| `/aep-design` | agentic-development-workflow | Explore + propose + review a feature | +| `/aep-launch` | agentic-development-workflow | Spawn workspace (Claude bg subagents/sessions; Codex subagents/exec; tmux when pinned) + optional evaluator | +| `/aep-build` | agentic-development-workflow | Implement → test → PR → merge | +| `/aep-wrap` | agentic-development-workflow | Archive + cleanup + suggest reflect | +| `/aep-git-ref` | agentic-development-workflow | AEP git + worktree conventions (on-demand) | +| `/aep-gen-eval` | patterns | Generator/evaluator separation for honest validation | +| `/aep-executor` | patterns | Host-agnostic backend for spawning/steering workspace agents | +| `/aep-autopilot` | patterns | Autonomous dispatch-launch-monitor-wrap loop via `/loop` | +| `/aep-workflow` | patterns | Dynamic workflows — author a custom multi-agent harness for a task (+ sub-pattern catalog) | +| `/aep-workflow-feedback` | patterns | Capture + review process learnings between downstream projects and AEP | +| `/aep-design-lens` | patterns | Theory-grounded design guideline + heuristic health-check (HCI/design-theory catalog + task/data lens selection) | +| `/aep-human-alignment` | human-alignment | One-page HTML project brief from `product-context.yaml` — where we are, what needs a human, where reality drifted | Launches are **native-first** with **hub-and-spoke human gates** — see [Launch modes](#launch-modes--native-first-executor-backends) and diff --git a/docs/human-alignment/example-looplia/README.md b/docs/human-alignment/example-looplia/README.md new file mode 100644 index 0000000..9ac5b6e --- /dev/null +++ b/docs/human-alignment/example-looplia/README.md @@ -0,0 +1,59 @@ +# Reference example: a real brief + +These files are the **unedited output** of `/aep-human-alignment` run against a +real consumer repo (looplia, 396 stories, 41 layer gates, 21 workspace packages) +at commit `65e359c6`. Nothing here was hand-tuned for presentation — the prose +was authored by the agent under the skill's rules, every number was bound by +`derive.mjs`, and `audit.mjs` passed before assembly. + +| File | What it is | +| -------------------------------------- | ------------------------------------------------------------- | +| `brief-2026-07-25T0308Z-65e359c6.html` | the delivered brief — one self-contained file, 3.2 MB | +| `facts.json` | Phase 1 output: the only legal source of numbers on that page | +| `code-graph.json` | Phase 1.5a output: the real package topology the scan found | +| `manifest.json` | the generation ledger — timestamps, commit, content SHA-256 | + +Open the HTML directly from disk; it needs no server. The five embedded archify +diagrams are inlined, so they render offline. The only network dependency is the +font CDN, which degrades to system fonts. + +## What it demonstrates + +- **The honesty model.** Open `facts.json` and grep the HTML for any number: all + 22 are `data-fact` bindings resolved at load. The agent wrote no digit. +- **Two-phase gate honesty.** The current layer's gate is `scripted_passed`, so + the Product band renders it under an `EXP` chip naming the acceptance run that + would settle it — not as a shipped capability. An earlier prototype of this + design asserted "acceptance passed" for exactly this gate; the rule exists + because of that failure. +- **Silence over fabrication.** `facts.json`'s `schema_absent` records three + predicates that could not be derived from this repo's schema at all (no + `product` section, no `status` on amendment-log entries, object maps live + outside the plan file). The brief surfaces the absence instead of reporting + "nothing needs you". +- **Derived drift only.** Eleven drift facts, every one with a YAML path. The + most interesting: the code is 21 packages while the plan file declares 32 + conceptual modules with **one** name in common and no path binding — so the + declared architecture is not code-addressable, and the brief says so rather + than pretending the two accounts agree. +- **Deterministic architecture.** The Engineering band's diagrams came from + `scan-workspace.mjs` → rules R1–R10 → archify `validate`/`deliver`, repaired + only through archify's own receipts (one round for the overview, two for the + package graph). + +## Known limitation, stated rather than hidden + +The domain overview lays out as a wide, shallow chain: looplia's dependency +graph is deep, and longest-path layering gives each depth its own column. It +passes archify's layout gates and it is honest, but a chain of that width is a +scan, not a glance — the glance gate in `references/checklist.md` is a P1 the +example only partly meets. Improving R7's grouping is the obvious next move. + +## Reproducing it + +The facts change every time the consumer's HEAD moves — that is the point of the +design, and it happened during development: one drift fact cited in the decision +doc (a gate with 38 criteria and zero coverage) had already resolved itself +before the implementation shipped. Re-running against looplia today will not +reproduce this file byte for byte; re-running at `65e359c6` reproduces the +diagrams byte for byte and the facts exactly, while the prose is authored fresh. diff --git a/docs/human-alignment/example-looplia/brief-2026-07-25T0308Z-65e359c6.html b/docs/human-alignment/example-looplia/brief-2026-07-25T0308Z-65e359c6.html new file mode 100644 index 0000000..e2a7d11 --- /dev/null +++ b/docs/human-alignment/example-looplia/brief-2026-07-25T0308Z-65e359c6.html @@ -0,0 +1,895 @@ + + + + + + looplia-run · project brief + + + + + + + +
+
+ +
+ looplia-run · brief + + + layer + open + needs you + +
+ + +
+
+

Overview · the whole thing at a glance

+

Looplia runs an AI company

+

Everything is moving except two repair jobs that only you can restart — they are the last things standing between the newsroom build-out and its sign-off.

+ +
+

Looplia gives AI agents the shape of employees: each has its own mailbox, can take a call, and shares a task board, while a company layer assigns work, checks capability, and keeps a replayable record of every run. The build right now is a professional newsroom — researchers verify claims, writers produce articles where every sentence carries its citation.

+

No product-vision field exists in this plan file, so this paragraph is written by the agent, not derived. Adding one would let it become a derived fact. · schema gap: product / opportunity sections absent

+

Overview · unchanged since this generation

+
+ +
+

Reset ▸

+

The post-deploy health check came back with a malformed error envelope, automatic repair has already given up, and the job is parked in a state only a person can move.

+

Read the failure log, set the task back to pending, then dispatch it again.

+

FIX-L32-CANARY-502-001 · stories[].status = failed · only a human may run failed → pending

+
+ +

One more repair sits behind it — a sandbox supervisor that will not start cleanly under a fresh identity. Read both failure logs together before deciding which to restart first. Beyond those, items in total are waiting on you, and nearly all of them are taste checkpoints that were planned but never run.

+

FIX-L32-SUPERVISOR-START-001 · calibration.plan minus calibration.history · predicates could not be derived from this plan file at all

+ +
+

Since the last brief

+

This is the first brief for this project, so there is no previous state to diff against. What the record shows instead is the newest stretch of work: the newsroom pipeline was wired end to end — the researcher re-verifies how current its sources are, the writer picks work off the formal assignment path and produces articles bound to their claims, and every run leaves a replayable trace. Two repairs opened in the same stretch and neither has closed.

+

changelog entries 2026-07-23 / 2026-07-24 · manifest.json absent at generation time = first run

+
+ +

+ Five cells = the five stages of a task; filled = reached. Exceptions are markers, not + stages — defined once in Engineering. Small type under a sentence is its source; you only + need it when checking. +

+
+
+ + +
+
+

Product · what it can do

+

What works today

+

The company layer, the agent workforce, and the newsroom pipeline are all built; what is not yet signed off is whether the newsroom holds up under a human's judgement.

+ +
+
+

Capabilities that have cleared acceptance

+

Across the build so far, acceptance runs have been signed off. Behind them sit the things you can actually use: agents that hold an identity and a mailbox, a shared task board they take work from, a company layer that grants and refuses capability, and a recorded, replayable trace of every run.

+

layer_gates[].status = passed · gates total

+
+
+

What changed for users recently

+

The newsroom went from parts to a production line: a researcher that re-checks whether its sources are still current, a writer that takes assignments through the formal routing path and emits articles whose every claim is linked to a source, and a fact-checker that reads the exact draft version rather than a summary of it.

+

changelog: L32-003 · L32-004 · L32-005 · L32-006 · L32-007 completed 2026-07-23/24

+
+
+

What the current stage will add

+

EXP → once the acceptance run for this stage passesThe newsroom's end-to-end run has passed its scripted check but not its human sign-off, so it is written here as an expectation rather than a fact. After it, the next stage is authority and governance: every action that reaches the outside world — publishing an article, for instance — has to clear a policy and permission gate first, which is what makes an autonomous newsroom safe to let out.

+

layer_gates[layer=32].status = scripted_passed (human acceptance not run) · L33-001…009 queued

+
+

Product · capability list unchanged since this generation

+
+ +

+ This list is derived from gates that reached passed; a gate that has only + passed its scripted run appears under an EXP chip naming the acceptance run that would + settle it. Nothing appears here on the strength of an unfinished gate. +

+
+
+ + +
+
+

Project · plan and progress

+

Where the plan has got to

+

Of tasks, are finished and are still open — and all but two of the open ones are simply waiting their turn.

+ +
+
+
+

What is queued behind this

+

Authority and governance comes next, then the stages that widen where material comes from and who is allowed to act on it. None of them has started; their tasks are written and waiting.

+
+ Show every open task, stage by stage +
    +
  • Authority and governance — policy, permission lattice, decision receipts
  • +
  • Dynamic source plane — widening where the newsroom draws material from
  • +
  • Later stages — written, queued, not yet opened
  • +
+
+

stories[].status = pending, grouped by layer · pending, deferred

+
+
+
+ + +
+
+

Project · ledger · facts that expire live here

+

What moved, and where reality drifted

+

places where the plan file and reality disagree — every one of them derived, none written from impression.

+ +
+

What moved

+

The newsroom pipeline landed across five tasks in two days, each merged through its own pull request with an independent evaluation before it counted as done. Two repair jobs opened against the same stage and are still open.

+

changelog[] 2026-07-23 → 2026-07-24 · stories[].status transitions

+
+ +
+

Where reality drifted

+
+

Work is marked done in stages that were never opened

+

Eight stages hold finished tasks while their acceptance run is still recorded as never started. Either the work outran its sign-off or the record was not kept up — both mean the control record no longer describes the project.

+

layer_gates[layer∈{2.5,3,5,7.5,13,27,28,29}].status = not_started with completed stories present

+
+
+

The code and the plan describe different systems

+

The code is packages joined by dependencies; the plan file describes conceptual modules, of which shares a name with anything that exists. No field binds a declared module to a source path, so the declared architecture cannot be checked against the code at all.

+

EXP → once modules[].paths lands in the schemaThe two accounts could then be reconciled automatically, and every declared dependency would become a lint rule with file and line evidence.

+

scan-workspace.mjs vs architecture.modules[] · modules carry a paths binding

+
+
+

Two repairs keep failing against the same subsystem

+

Both open repair jobs carry a failure log, which is the shape of a specification and an implementation disagreeing rather than a flaky run. Finished tasks that once failed are not counted here; their logs are history.

+

stories[].failure_logs on open stories only

+
+
+

One acceptance state is not in the vocabulary

+

A single stage records a sign-off state that the system does not define, which means the control file's own wording has started to drift.

+

layer_gates[layer=20].status = "completed" (defined states: not_started → scripted_passed → passed)

+
+
+

Spending is declared but never wired up

+

The cost plane totals zero while tasks carry free-text token notes, so this brief cannot tell you what the project has cost.

+

cost.total_usd = 0 · cost.by_story is prose, not numbers

+
+
+ +

+ Every drift row is derived and cites its source — none is written from impression. + Unchipped = fact; EXP = an expectation, with the condition that would settle it. +

+
+
+ + +
+
+

Engineering · the system itself

+

What the system is made of

+

A deterministic scan reads the real package graph from the workspace manifest and groups it into domains; the plan file's own account of the architecture is shown beside it, and it does not match.

+ +
+
+
+

scan-workspace.mjs → rules R1–R10 → archify validate/deliver · code-verified at package level · commit

+

The default view is the domain grouping. The deep-dive shows every package the rules kept; the declared narrative is the plan file's account, which is authored, not verified. Where the first two and the third disagree, that disagreement is recorded in the ledger above rather than quietly reconciled.

+

Engineering · architecture unchanged since this generation

+
+ +
+

How the project moves, and the five stages of a task

+

These two diagrams are the only place this brief's vocabulary is defined. Solid lines are the normal path — the same five cells that sit beside every task row above. Dashed lines are exception markers. The step from failed back to pending is one only a person may take, which is why the top of this page has an ask at all.

+
+
+

Engineering · loop and states unchanged since this generation

+
+ +
+

How to check any of this

+

Every number on this page is bound to a field in a machine-derived facts file; none was typed by the agent that wrote the prose. The small type under each statement names the field it came from, so any claim here can be traced back to the plan file or to the code scan. An independent audit re-checks those bindings before the page is written.

+

The audit could not derive of its signals from this plan file because the fields they need are absent. They are recorded as unavailable rather than reported as clear.

+

+
+
+
+ + + + + + + + diff --git a/docs/human-alignment/example-looplia/code-graph.json b/docs/human-alignment/example-looplia/code-graph.json new file mode 100644 index 0000000..90abcd9 --- /dev/null +++ b/docs/human-alignment/example-looplia/code-graph.json @@ -0,0 +1,441 @@ +{ + "repo": "looplia", + "commit": "65e359c6", + "tool": "scan-workspace.mjs (package.json workspace graph, deterministic)", + "nodes": 21, + "edges": 75, + "apps": 3, + "packages": 17, + "package_names": [ + "@looplia/agent", + "server", + "web", + "@looplia/agent-runtime", + "@looplia/api", + "@looplia/auth", + "@looplia/config", + "@looplia/db", + "@looplia/do-agent", + "@looplia/do-container", + "@looplia/do-relay", + "@looplia/do-sidecar", + "@looplia/agent-e2e-test", + "@looplia/email-protocol", + "@looplia/email-sdk-ts", + "@looplia/env", + "@looplia/infra", + "@looplia/protocol", + "@looplia/ui", + "@looplia/voice", + "@looplia/e2e-test" + ], + "nodes_detail": [ + { + "name": "@looplia/agent", + "dir": "apps/agent", + "private": true + }, + { + "name": "server", + "dir": "apps/server", + "private": false + }, + { + "name": "web", + "dir": "apps/web", + "private": true + }, + { + "name": "@looplia/agent-runtime", + "dir": "packages/agent-runtime", + "private": true + }, + { + "name": "@looplia/api", + "dir": "packages/api", + "private": false + }, + { + "name": "@looplia/auth", + "dir": "packages/auth", + "private": false + }, + { + "name": "@looplia/config", + "dir": "packages/config", + "private": true + }, + { + "name": "@looplia/db", + "dir": "packages/db", + "private": false + }, + { + "name": "@looplia/do-agent", + "dir": "packages/do-agent", + "private": true + }, + { + "name": "@looplia/do-container", + "dir": "packages/do-container", + "private": true + }, + { + "name": "@looplia/do-relay", + "dir": "packages/do-relay", + "private": true + }, + { + "name": "@looplia/do-sidecar", + "dir": "packages/do-sidecar", + "private": true + }, + { + "name": "@looplia/agent-e2e-test", + "dir": "packages/e2e-test", + "private": true + }, + { + "name": "@looplia/email-protocol", + "dir": "packages/email-protocol", + "private": true + }, + { + "name": "@looplia/email-sdk-ts", + "dir": "packages/email-sdk-ts", + "private": false + }, + { + "name": "@looplia/env", + "dir": "packages/env", + "private": true + }, + { + "name": "@looplia/infra", + "dir": "packages/infra", + "private": true + }, + { + "name": "@looplia/protocol", + "dir": "packages/protocol", + "private": true + }, + { + "name": "@looplia/ui", + "dir": "packages/ui", + "private": true + }, + { + "name": "@looplia/voice", + "dir": "packages/voice", + "private": true + }, + { + "name": "@looplia/e2e-test", + "dir": "tests/e2e", + "private": true + } + ], + "edges_detail": [ + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/agent-runtime" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/api" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/auth" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/config" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/db" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/do-agent" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/do-container" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/do-relay" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/email-protocol" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/env" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/protocol" + }, + { + "from": "@looplia/agent-e2e-test", + "to": "@looplia/voice" + }, + { + "from": "@looplia/agent-runtime", + "to": "@looplia/config" + }, + { + "from": "@looplia/api", + "to": "@looplia/auth" + }, + { + "from": "@looplia/api", + "to": "@looplia/config" + }, + { + "from": "@looplia/api", + "to": "@looplia/db" + }, + { + "from": "@looplia/api", + "to": "@looplia/email-protocol" + }, + { + "from": "@looplia/api", + "to": "@looplia/env" + }, + { + "from": "@looplia/api", + "to": "@looplia/protocol" + }, + { + "from": "@looplia/auth", + "to": "@looplia/config" + }, + { + "from": "@looplia/auth", + "to": "@looplia/db" + }, + { + "from": "@looplia/auth", + "to": "@looplia/env" + }, + { + "from": "@looplia/db", + "to": "@looplia/config" + }, + { + "from": "@looplia/db", + "to": "@looplia/email-protocol" + }, + { + "from": "@looplia/db", + "to": "@looplia/env" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/agent-runtime" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/api" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/config" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/db" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/do-relay" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/email-protocol" + }, + { + "from": "@looplia/do-agent", + "to": "@looplia/protocol" + }, + { + "from": "@looplia/do-container", + "to": "@looplia/config" + }, + { + "from": "@looplia/do-relay", + "to": "@looplia/config" + }, + { + "from": "@looplia/do-relay", + "to": "@looplia/protocol" + }, + { + "from": "@looplia/do-sidecar", + "to": "@looplia/config" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/api" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/auth" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/config" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/db" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/do-relay" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/env" + }, + { + "from": "@looplia/e2e-test", + "to": "@looplia/protocol" + }, + { + "from": "@looplia/email-protocol", + "to": "@looplia/config" + }, + { + "from": "@looplia/email-sdk-ts", + "to": "@looplia/config" + }, + { + "from": "@looplia/email-sdk-ts", + "to": "@looplia/email-protocol" + }, + { + "from": "@looplia/env", + "to": "@looplia/config" + }, + { + "from": "@looplia/env", + "to": "@looplia/infra" + }, + { + "from": "@looplia/infra", + "to": "@looplia/config" + }, + { + "from": "@looplia/protocol", + "to": "@looplia/config" + }, + { + "from": "@looplia/ui", + "to": "@looplia/config" + }, + { + "from": "@looplia/voice", + "to": "@looplia/agent-runtime" + }, + { + "from": "@looplia/voice", + "to": "@looplia/api" + }, + { + "from": "@looplia/voice", + "to": "@looplia/config" + }, + { + "from": "@looplia/voice", + "to": "@looplia/db" + }, + { + "from": "@looplia/voice", + "to": "@looplia/do-agent" + }, + { + "from": "server", + "to": "@looplia/agent-runtime" + }, + { + "from": "server", + "to": "@looplia/api" + }, + { + "from": "server", + "to": "@looplia/auth" + }, + { + "from": "server", + "to": "@looplia/config" + }, + { + "from": "server", + "to": "@looplia/db" + }, + { + "from": "server", + "to": "@looplia/do-agent" + }, + { + "from": "server", + "to": "@looplia/do-container" + }, + { + "from": "server", + "to": "@looplia/do-relay" + }, + { + "from": "server", + "to": "@looplia/email-protocol" + }, + { + "from": "server", + "to": "@looplia/env" + }, + { + "from": "server", + "to": "@looplia/voice" + }, + { + "from": "web", + "to": "@looplia/api" + }, + { + "from": "web", + "to": "@looplia/auth" + }, + { + "from": "web", + "to": "@looplia/config" + }, + { + "from": "web", + "to": "@looplia/db" + }, + { + "from": "web", + "to": "@looplia/env" + }, + { + "from": "web", + "to": "@looplia/protocol" + }, + { + "from": "web", + "to": "@looplia/ui" + }, + { + "from": "web", + "to": "@looplia/voice" + } + ] +} diff --git a/docs/human-alignment/example-looplia/facts.json b/docs/human-alignment/example-looplia/facts.json new file mode 100644 index 0000000..27c7916 --- /dev/null +++ b/docs/human-alignment/example-looplia/facts.json @@ -0,0 +1,4858 @@ +{ + "schema_version": 1, + "generated_from": "product-context.yaml", + "commit": "65e359c6", + "baseline_commit": null, + "project": "looplia-run", + "version": "0.5.3", + "updated_at": "2026-07-24", + "story_total": 396, + "by_status": { + "completed": 333, + "deferred": 16, + "failed": 2, + "ready": 1, + "pending": 44 + }, + "open_total": 47, + "current_layer": 32, + "attention_set": [ + { + "rank": 1, + "kind": "failed", + "verb": "reset", + "id": "FIX-L32-CANARY-502-001", + "title": "Diagnose non-contract Sandbox canary 502 envelope", + "layer": 32, + "path": "stories[id=FIX-L32-CANARY-502-001].status", + "why": null + }, + { + "rank": 1, + "kind": "failed", + "verb": "reset", + "id": "FIX-L32-SUPERVISOR-START-001", + "title": "Stabilize fresh-identity Sandbox supervisor start", + "layer": 32, + "path": "stories[id=FIX-L32-SUPERVISOR-START-001].status", + "why": null + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-1.5-api-surface", + "title": "api-surface", + "layer": 1.5, + "path": "calibration.plan[1]", + "why": "Layer 1 agent platform complete — calibrate agent UX and wire protocol surface" + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-1.5-ux-flow", + "title": "ux-flow", + "layer": 1.5, + "path": "calibration.plan[1]", + "why": "Layer 1 agent platform complete — calibrate agent UX and wire protocol surface" + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-7.5-copy-tone", + "title": "copy-tone", + "layer": 7.5, + "path": "calibration.plan[4]", + "why": "Brand & landing redesign (auto-company pivot) — calibrate the liquid-glass + parallax visual direction against real app shell tokens (screenshots, not standalone HTML) and the AI-employees positioning copy before the landing ships." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-7.5-visual-design", + "title": "visual-design", + "layer": 7.5, + "path": "calibration.plan[4]", + "why": "Brand & landing redesign (auto-company pivot) — calibrate the liquid-glass + parallax visual direction against real app shell tokens (screenshots, not standalone HTML) and the AI-employees positioning copy before the landing ships." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-9-api-surface", + "title": "api-surface", + "layer": 9, + "path": "calibration.plan[5]", + "why": "L9a work system shipped — calibrate the task board / heartbeat comment / approval card flows and the task+approval API shapes before L9b builds the management layer on top." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-9-ux-flow", + "title": "ux-flow", + "layer": 9, + "path": "calibration.plan[5]", + "why": "L9a work system shipped — calibrate the task board / heartbeat comment / approval card flows and the task+approval API shapes before L9b builds the management layer on top." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-10.5-visual-design", + "title": "visual-design", + "layer": 10.5, + "path": "calibration.plan[6]", + "why": "Post-L10 dogfood surfaced company-surface gaps (modals, missing company IA, node assignment, work board readability, no company overview) — direction captured 2026-06-11 in calibration/company-surface.yaml before the L105 wave builds." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-11.5-ux-flow", + "title": "ux-flow", + "layer": 11.5, + "path": "calibration.plan[7]", + "why": "Cockpit wave (2026-06-12 owner feedback): mobile entry points broken, company/agent grouping muddled, Coordination section ambiguous, work board needs Trello-style readability + run observability — calibrate the IA regroup, bottom-tab nav, and board drag semantics on real viewports before/while 11.5 builds." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-12-performance-quality", + "title": "performance-quality", + "layer": 12, + "path": "calibration.plan[8]", + "why": "Voice MVP first working calls — calibrate by LISTENING on a real call (not reading metrics): time-to-first-audio feel, filler-phrase script + cadence during tool work, barge-in stop time, idle/cap hangup copy, mic affordance + call overlay + voice chip rendering. TTS provider decision (Kokoro vs Aura-1) reviewed against the spike's TTFB numbers here." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-12-ux-flow", + "title": "ux-flow", + "layer": 12, + "path": "calibration.plan[8]", + "why": "Voice MVP first working calls — calibrate by LISTENING on a real call (not reading metrics): time-to-first-audio feel, filler-phrase script + cadence during tool work, barge-in stop time, idle/cap hangup copy, mic affordance + call overlay + voice chip rendering. TTS provider decision (Kokoro vs Aura-1) reviewed against the spike's TTFB numbers here." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-13-api-surface", + "title": "api-surface", + "layer": 13, + "path": "calibration.plan[9]", + "why": "Minimal Layer 13 slice (skill packages + formation + hiring + freshness) — calibrate whether the company-agent formation, hire-agent provisioning, and freshness boundaries are the right product direction and data contracts before they become the durable company operating layer. (Platform deepening deferred to Layer 14; generative company UI to Layer 14.5.)" + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-13-data-model", + "title": "data-model", + "layer": 13, + "path": "calibration.plan[9]", + "why": "Minimal Layer 13 slice (skill packages + formation + hiring + freshness) — calibrate whether the company-agent formation, hire-agent provisioning, and freshness boundaries are the right product direction and data contracts before they become the durable company operating layer. (Platform deepening deferred to Layer 14; generative company UI to Layer 14.5.)" + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-13-scope-direction", + "title": "scope-direction", + "layer": 13, + "path": "calibration.plan[9]", + "why": "Minimal Layer 13 slice (skill packages + formation + hiring + freshness) — calibrate whether the company-agent formation, hire-agent provisioning, and freshness boundaries are the right product direction and data contracts before they become the durable company operating layer. (Platform deepening deferred to Layer 14; generative company UI to Layer 14.5.)" + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14-api-surface", + "title": "api-surface", + "layer": 14, + "path": "calibration.plan[10]", + "why": "[deferred] AI-Company FDE platform deepening — calibrate the typed company-fact graph, connector-observer event/candidate model, and FDE readiness/cockpit contracts before they become durable. Activates only when Layer 14 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14-data-model", + "title": "data-model", + "layer": 14, + "path": "calibration.plan[10]", + "why": "[deferred] AI-Company FDE platform deepening — calibrate the typed company-fact graph, connector-observer event/candidate model, and FDE readiness/cockpit contracts before they become durable. Activates only when Layer 14 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14-scope-direction", + "title": "scope-direction", + "layer": 14, + "path": "calibration.plan[10]", + "why": "[deferred] AI-Company FDE platform deepening — calibrate the typed company-fact graph, connector-observer event/candidate model, and FDE readiness/cockpit contracts before they become durable. Activates only when Layer 14 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14.5-api-surface", + "title": "api-surface", + "layer": 14.5, + "path": "calibration.plan[11]", + "why": "[deferred] Voice + generative company UI — prove a spoken/typed request becomes a durable, editable, live-bound company dashboard (not just chat). Activates only when Layer 14.5 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14.5-ux-flow", + "title": "ux-flow", + "layer": 14.5, + "path": "calibration.plan[11]", + "why": "[deferred] Voice + generative company UI — prove a spoken/typed request becomes a durable, editable, live-bound company dashboard (not just chat). Activates only when Layer 14.5 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-14.5-visual-design", + "title": "visual-design", + "layer": 14.5, + "path": "calibration.plan[11]", + "why": "[deferred] Voice + generative company UI — prove a spoken/typed request becomes a durable, editable, live-bound company dashboard (not just chat). Activates only when Layer 14.5 is undeferred." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-21-api-surface", + "title": "api-surface", + "layer": 21, + "path": "calibration.plan[12]", + "why": "PRE-BUILD checkpoint before L21-002 dispatches: align the trajectory entry/detail DATA SHAPE (the list row { kind, ts, source, title, summary, status, stepCount } + the run-vs-chat detail payload + entryId encoding) — it becomes the agent.trajectory.list/detail RPC contract that L21-003, L21-004, and the gate all consume, so a wrong shape is expensive to change post-freeze. Light checkpoint (no .5 layer), decisions update product-context.yaml directly." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-21-ux-flow", + "title": "ux-flow", + "layer": 21, + "path": "calibration.plan[12]", + "why": "PRE-BUILD checkpoint before L21-002 dispatches: align the trajectory entry/detail DATA SHAPE (the list row { kind, ts, source, title, summary, status, stepCount } + the run-vs-chat detail payload + entryId encoding) — it becomes the agent.trajectory.list/detail RPC contract that L21-003, L21-004, and the gate all consume, so a wrong shape is expensive to change post-freeze. Light checkpoint (no .5 layer), decisions update product-context.yaml directly." + }, + { + "rank": 4, + "kind": "calibration_due", + "verb": "/aep-calibrate", + "id": "calibration-21.5-visual-design", + "title": "visual-design", + "layer": 21.5, + "path": "calibration.plan[13]", + "why": "Layer 21 ships the autonomy-first surface — calibrate the aggregated trajectory log (row->modal drill-down; reasoning + tool calls + files read at a glance; live active runs), the reshaped Agents-page IA (Company / Agent / Settings), and the Company page cockpit (#general chat placement, Company Vision panel, moved work/messaging/activity) on mobile + desktop, on real prod data." + } + ], + "one_ask": { + "rank": 1, + "kind": "failed", + "verb": "reset", + "id": "FIX-L32-CANARY-502-001", + "title": "Diagnose non-contract Sandbox canary 502 envelope", + "layer": 32, + "path": "stories[id=FIX-L32-CANARY-502-001].status", + "why": null + }, + "schema_absent": [ + { + "predicate": "amendment_pending", + "path": "architecture.amendment_log[].status", + "reason": "field absent in this schema version — pending amendments are not derivable" + }, + { + "predicate": "open_question", + "path": "product.open_questions[]", + "reason": "section absent in this schema version — open questions are not derivable" + }, + { + "predicate": "draft_object_map", + "path": "product/maps/*/object-map.yaml#status", + "reason": "object maps are separate artifacts — not derivable from product-context.yaml alone" + } + ], + "drift_facts": [ + { + "kind": "reality_resisting_intent", + "layer": 32, + "detail": "FIX-L32-SUPERVISOR-START-001 has 1 failure log and is still open (failed)", + "path": "stories[id=FIX-L32-SUPERVISOR-START-001].failure_logs", + "level": "derived", + "counters": { + "failure_logs": 1 + } + }, + { + "kind": "reality_resisting_intent", + "layer": 32, + "detail": "FIX-L32-CANARY-502-001 has 1 failure log and is still open (failed)", + "path": "stories[id=FIX-L32-CANARY-502-001].failure_logs", + "level": "derived", + "counters": { + "failure_logs": 1 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 2.5, + "detail": "10 completed stories under a not_started gate", + "path": "layer_gates[layer=2.5].status", + "level": "derived", + "counters": { + "completed_stories": 10, + "layer_stories": 10 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 3, + "detail": "2 completed stories under a not_started gate", + "path": "layer_gates[layer=3].status", + "level": "derived", + "counters": { + "completed_stories": 2, + "layer_stories": 3 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 5, + "detail": "2 completed stories under a not_started gate", + "path": "layer_gates[layer=5].status", + "level": "derived", + "counters": { + "completed_stories": 2, + "layer_stories": 4 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 7.5, + "detail": "1 completed story under a not_started gate", + "path": "layer_gates[layer=7.5].status", + "level": "derived", + "counters": { + "completed_stories": 1, + "layer_stories": 1 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 13, + "detail": "11 completed stories under a not_started gate", + "path": "layer_gates[layer=13].status", + "level": "derived", + "counters": { + "completed_stories": 11, + "layer_stories": 11 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 27, + "detail": "6 completed stories under a not_started gate", + "path": "layer_gates[layer=27].status", + "level": "derived", + "counters": { + "completed_stories": 6, + "layer_stories": 6 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 28, + "detail": "5 completed stories under a not_started gate", + "path": "layer_gates[layer=28].status", + "level": "derived", + "counters": { + "completed_stories": 5, + "layer_stories": 5 + } + }, + { + "kind": "control_plane_incoherence", + "layer": 29, + "detail": "4 completed stories under a not_started gate", + "path": "layer_gates[layer=29].status", + "level": "derived", + "counters": { + "completed_stories": 4, + "layer_stories": 4 + } + }, + { + "kind": "declared_vs_actual", + "layer": null, + "detail": "code has 21 workspace packages, the YAML declares 32 conceptual modules, 1 names in common; no architecture.modules[].paths binds them, so declared edges are not code-addressable", + "path": "architecture.modules[].paths", + "level": "code-verified", + "counters": { + "code_packages": 21, + "declared_modules": 32, + "name_overlap": 1 + } + } + ], + "gates": { + "total": 42, + "by_status": { + "passed": 19, + "not_started": 16, + "scripted_passed": 4, + "deferred": 2, + "completed": 1 + }, + "vocabulary_violations": [ + { + "layer": 20, + "status": "completed", + "path": "layer_gates[layer=20].status" + } + ], + "detail": [ + { + "layer": 0, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-04-07", + "shippable": true + }, + { + "layer": 0.5, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-04-07", + "shippable": true + }, + { + "layer": 1, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-04-09", + "shippable": true + }, + { + "layer": 2, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-05-04", + "shippable": true + }, + { + "layer": 2.5, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 3, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 4, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-05-27T10:13:59Z", + "shippable": true + }, + { + "layer": 4.5, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-05-29", + "shippable": true + }, + { + "layer": 5, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 7.5, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 8, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-10", + "shippable": true + }, + { + "layer": 9, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-10", + "shippable": true + }, + { + "layer": 10, + "status": "scripted_passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 10.5, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-11", + "shippable": true + }, + { + "layer": 11, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-12", + "shippable": true + }, + { + "layer": 11.5, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-12", + "shippable": true + }, + { + "layer": 12, + "status": "scripted_passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 13, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 14, + "status": "deferred", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 14.5, + "status": "deferred", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 18, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-17", + "shippable": true + }, + { + "layer": 18.5, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-26", + "shippable": true + }, + { + "layer": 19, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-18", + "shippable": true + }, + { + "layer": 20, + "status": "completed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 21, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-20", + "shippable": true + }, + { + "layer": 23, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-24", + "shippable": true + }, + { + "layer": 24, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-28", + "shippable": true + }, + { + "layer": 25, + "status": "passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-06-30", + "shippable": true + }, + { + "layer": 26, + "status": "scripted_passed", + "criteria_total": null, + "criteria_covered": null, + "completed_at": "2026-07-02T10:02:00Z", + "shippable": false + }, + { + "layer": 27, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 28, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 29, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + }, + { + "layer": 31, + "status": "passed", + "criteria_total": 75, + "criteria_covered": 75, + "completed_at": "2026-07-18T10:44:00Z", + "shippable": true + }, + { + "layer": 32, + "status": "scripted_passed", + "criteria_total": 38, + "criteria_covered": 38, + "completed_at": null, + "shippable": false + }, + { + "layer": 33, + "status": "not_started", + "criteria_total": 39, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 34, + "status": "not_started", + "criteria_total": 33, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 35, + "status": "not_started", + "criteria_total": 26, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 36, + "status": "not_started", + "criteria_total": 16, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 37, + "status": "not_started", + "criteria_total": 24, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 38, + "status": "not_started", + "criteria_total": 20, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 39, + "status": "not_started", + "criteria_total": 25, + "criteria_covered": 0, + "completed_at": null, + "shippable": false + }, + { + "layer": 41, + "status": "not_started", + "criteria_total": null, + "criteria_covered": null, + "completed_at": null, + "shippable": false + } + ] + }, + "layers": [ + { + "layer": 0, + "counts": { + "completed": 17 + }, + "total": 17, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-001", + "title": "Wire protocol session lifecycle messages", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-002", + "title": "DB schema for daemon and session_ticket tables", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-003", + "title": "Infra: add Durable Object binding to Worker", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-004", + "title": "Web signup and login flow verification", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-005", + "title": "Daemon config and keychain integration", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-006", + "title": "API: daemon CRUD endpoints", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-007", + "title": "SessionRelay DO with WebSocket Hibernation", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-008", + "title": "CLI: device OAuth login flow", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-009", + "title": "API: session ticket endpoint", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-010", + "title": "Daemon: browser OAuth registration flow", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-011", + "title": "Daemon: WebSocket connect + auto-reconnect", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-012", + "title": "CLI: list daemons command", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-013", + "title": "Web: dashboard daemon list", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-014", + "title": "API: WebSocket upgrade route with ticket auth", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-015", + "title": "Daemon: PTY spawn and I/O relay", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-016", + "title": "CLI: connect command with PTY passthrough", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-017", + "title": "Integration: end-to-end PTY session test", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 0.5, + "counts": { + "completed": 7 + }, + "total": 7, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-P01", + "title": "Landing page: hero, value prop, install instructions", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P02", + "title": "Auth pages design polish: sign-up and login", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P03", + "title": "Dashboard detail: daemon connections and session history", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P04", + "title": "E2E visual test: seed user, connect daemon, verify UI", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P05", + "title": "Fix binary frame format mismatch between DO relay and Rust daemon", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P07", + "title": "Replace keychain with dotfile credential storage (AWS-style)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-P06", + "title": "Fix CLI auth: add Bearer token session validation to API server", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 1, + "counts": { + "completed": 11 + }, + "total": 11, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-020", + "title": "Blocklist schema and daemon-side enforcement", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-021", + "title": "Heartbeat alarm and response handling", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-022", + "title": "Audit log schema and buffered D1 writes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-023", + "title": "Audit log query API", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-024", + "title": "Web: audit log viewer page", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-025", + "title": "Web: guardrails configuration page", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-026", + "title": "Agent container image with PTY server + Pi-Mono + looplia-run", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-027", + "title": "Daemon Dockerfile and k3s manifest", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-028", + "title": "AgentContainer Durable Object + Alchemy IaC", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-029", + "title": "WebSocket terminal proxy route", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-030", + "title": "Web: Ghostty terminal page for agent", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 2, + "counts": { + "completed": 22 + }, + "total": 22, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-031", + "title": "Rename /dashboard/agent route to /dashboard/terminal + accept ?ticket= param", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-032", + "title": "Rename /ws/agent to /ws/terminal + update header nav", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-033", + "title": "Add agents@0.11.9 and LoopliaAgent DO skeleton", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-034", + "title": "/agui Hono endpoint with AG-UI SSE scaffolding", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-035", + "title": "Agent tool: list_daemons (+ tool barrel scaffolding)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-036", + "title": "Agent tool: run_shell (SessionRelay exec helper + tool)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-037", + "title": "Agent tool: open_terminal (handoff to /dashboard/terminal)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-038", + "title": "Agent tools: get_audit_log, list_guardrails, update_guardrail (+ guardrailsRouter.upsert)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-039", + "title": "CopilotKit provider + /dashboard/agent chat shell", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-040", + "title": "Generative UI: TerminalCard, DaemonList, AuditTable, GuardrailEditor, TerminalHandoff", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-041", + "title": "useCoAgent state sync (live node map)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-042", + "title": "Layer 2 integration gate (E2E agent conversation)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-043", + "title": "HUD frame polish + CopilotKit theming", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-044", + "title": "AI Gateway binding + model call routing through CF AI Gateway", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx1", + "title": "Multi-provider abstraction + Workers AI default + gateway-compat client", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx5", + "title": "Codex Responses provider (chatgpt.com/backend-api/codex/responses, JWT account-id, DO-serialized refresh)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx6", + "title": "Daemon codex_oauth Rust module (PKCE, localhost:1455 listener, browser open, token exchange, JWT decode)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx7", + "title": "Wire protocol: codex_login_request/result frames + SessionRelay routing + runCodexLogin RPC", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx8", + "title": "connect_codex agent tool (guardrail approval, dispatch via SessionRelay, JWT defense, DO loadCodexAuth)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx9", + "title": "Dispatcher fallback chain (5xx/429/network → next provider, RAW providerFallback event)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx10", + "title": "/dashboard/settings/llm-provider page + CodexAuthStatus badge + per-user override RPC", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-Bx11", + "title": "Setup guide (docs/setup/llm-providers.md)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 2.5, + "counts": { + "completed": 10 + }, + "total": 10, + "gate_status": "not_started", + "is_current": false, + "stories": [ + { + "id": "LR-045", + "title": "D1 story schema (stories, story_comments, story_blockers) + Drizzle migration", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-046", + "title": "storyRouter oRPC: list / get / create / update / cancel (owner-scoped)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-047", + "title": "Frame protocol extension: STORY_START / STORY_PROGRESS / STORY_RESULT / STORY_CANCEL", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-048", + "title": "Daemon-side STORY runner: spawn bash subprocess, stream PROGRESS, emit RESULT", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-049", + "title": "Daemon capability handshake (daemon_capabilities CONTROL message)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-050", + "title": "packages/agent-runtime + LoopliaAgent fiber tools (run_long_shell, cancel_story) + STATE_DELTA progress emission", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-051", + "title": " generative UI with live progress bar", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-052", + "title": " sidebar widget on /dashboard/agent", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-053", + "title": "Layer 2.5 integration gate (yt-dlp + whisper scenario, stub model + stub daemon)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-054", + "title": "Replace misleading 'context window' fallback with honest upstream-availability message", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 3, + "counts": { + "completed": 2, + "deferred": 1 + }, + "total": 3, + "gate_status": "not_started", + "is_current": false, + "stories": [ + { + "id": "LR-055", + "title": "Real-model smoke test in CI: catch upstream-availability failures before deploy", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-056", + "title": "Throttle storyRouter.list polling when no stories are in flight", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-091", + "title": "Audit all Durable Objects for in-memory state that doesn't survive hibernation", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": null + } + ] + }, + { + "layer": 4, + "counts": { + "completed": 17 + }, + "total": 17, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-057", + "title": "D1 migration: add user.slug column with backfill", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-059", + "title": "packages/email-protocol — Zod schemas for email wire types", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-060", + "title": "Alchemy infra: R2 bucket, EMAIL binding, Email Routing catch-all rule", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-058", + "title": "Drizzle schema + D1 migration for agent_email table", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-061", + "title": "LoopliaAgent SQLite: add email_message table + onStart migration", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-063", + "title": "email-outbound: buildMime helper + HMAC reply-routing header", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-067", + "title": "oRPC: agentEmail.create / list / update / delete procedures", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-062", + "title": "LoopliaAgent.onEmail — inbound handler", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-064", + "title": "LoopliaAgent.sendEmail — outbound handler", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-065", + "title": "LoopliaAgent.listMessages / getMessage / getRaw RPC methods", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-070", + "title": "Web: /agents/email — list addresses + create form", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-066", + "title": "apps/server: email() handler + custom address resolver", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-068", + "title": "oRPC: agentEmail.listMessages + agentEmail.getMessage", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-069", + "title": "oRPC: agentEmail.send", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-071", + "title": "Web: /agents/email/:id — inbox list with read/unread + folder tabs", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-072", + "title": "Web: message view + Reply composer", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-073", + "title": "Layer 4 gate: E2E inbound + outbound + threading + DKIM", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 4.5, + "counts": { + "completed": 17 + }, + "total": 17, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "LR-074", + "title": "Drizzle schema + D1 migration for agent_email_api_key + agent_email_webhook", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-075", + "title": "email-api: Bearer aelk_ auth middleware + scope check", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-080", + "title": "oRPC: agentEmail.createKey / listKeys / revokeKey / createWebhook / listWebhooks / deleteWebhook", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-083", + "title": "LoopliaAgent: enqueue email.received / email.delivered / email.bounced events", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-076", + "title": "email-api: Workers Rate Limiting binding wiring + per-key bucket", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-077", + "title": "email-api: Idempotency-Key dedup (5-min window)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-079", + "title": "email-api: REST /v1/email/keys + /v1/email/webhooks CRUD", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-081", + "title": "Web: API key + webhook management UI", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-084", + "title": "email-webhooks: Cloudflare Queue consumer Worker + HMAC signer + retry", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-085", + "title": "CLI: looplia email login — browser OAuth → aelk_ key + OS keyring storage", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-078", + "title": "email-api: REST /v1/email/* message + thread + search + draft routes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-082", + "title": "email-api: MCP server at /mcp — streamable HTTP, 12 tools", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-086", + "title": "CLI: looplia email send / read / show / search / reply subcommands", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-087", + "title": "CLI: looplia email keys / webhooks subcommands", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-089", + "title": "packages/email-sdk-ts: typed TypeScript SDK wrapping REST", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-088", + "title": "CLI: looplia email watch — SSE stream of new-mail events", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "LR-090", + "title": "Layer 4.5 gate: MCP + REST + CLI + webhook E2E", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 5, + "counts": { + "deferred": 2, + "completed": 2 + }, + "total": 4, + "gate_status": "not_started", + "is_current": false, + "stories": [ + { + "id": "LR-018", + "title": "MCP Streamable HTTP endpoint with daemon discovery", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": null + }, + { + "id": "LR-019", + "title": "MCP execute_command tool", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": null + }, + { + "id": "FIX-AUTH-001", + "title": "Fix: user signup broken — slug derivation reads undefined user.id in better-auth 1.5.5 create.before hook", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "FIX-AGENT-001", + "title": "Fix: agent tool-calling broken — TOOL_CALL_START never fires in the LR-Bx1 multi-provider model-adapter / /agui flow", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 6, + "counts": { + "completed": 10 + }, + "total": 10, + "gate_status": null, + "is_current": false, + "stories": [ + { + "id": "L6-001", + "title": "Stateful daemon exec-session channel (persistent shell over a dedicated agent-exec channel, not the human PTY)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-002", + "title": "agent_run primitive — host the brain's reasoning loop as a durable Think fiber (survives DO eviction, escapes the 60s/maxToolLoops ceiling)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-003", + "title": "Unified daemon-control tools — create_session / shell / kill_session + ExecutionTarget (retire stateless run_shell)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-004", + "title": "Session reaper — DO alarm-based idle-session GC (the sleepAfter analog; no leaked live shells)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-005", + "title": "Layer 6 Wave-1 gate — read-only stateful daemon control E2E, survives simulated eviction", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-009", + "title": "Think base-class + Persistent Sessions migration (enabler for context blocks + Workspace memory)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-010", + "title": "Workspace memory filesystem wiring (cloudflare/shell Workspace + MEMORY_BUCKET R2 + git + createWorkspaceTools)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-011", + "title": "consolidateMemory commit loop — scheduled fiber distills sessions into /memory + /skills files, git-committed", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-012", + "title": "Memory injection — withContext(memory) hot block + per-turn file retrieval (active machine file + glob/grep over /skills)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L6-013", + "title": "Codemode edge tier — DynamicWorkerExecutor runs LLM-written JS against the Workspace (target=edge; execute /skills codemode blocks)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 7, + "counts": { + "completed": 25, + "deferred": 1 + }, + "total": 26, + "gate_status": null, + "is_current": false, + "stories": [ + { + "id": "L7-001", + "title": "Agent Web Shell — 3-region agent-IDE layout (LEFT control plane · CENTER chat · RIGHT resource inspector), responsive, UI-only with mock data", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-002", + "title": "Wire conversation history — listThreads/getThreadMessages read path over assistant_messages, URL-driven thread selection, CENTER hydration", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-003", + "title": "Wire RIGHT inspector real data — workspace Files tree, embedded Terminal PTY, real Memory + bound Node", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004", + "title": "Agent-owned mailboxes + Messaging console EPIC", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004a", + "title": "Agent mailbox ownership invariant + default mailbox provisioning", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004b", + "title": "Agent mail tools -- list/search/read/send/reply over agent-owned mailboxes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004c", + "title": "Messaging console -- browse and search all agent mailboxes or one agent's mailboxes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004d", + "title": "Layer 7 Messaging gate -- agent-owned mailboxes, tools, and console E2E", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004e", + "title": "Create-agent dialog -- default mailbox is automatic, not optional", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004f", + "title": "Active-agent Email tab -- add another mailbox", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004g", + "title": "Messaging console -- search input visible and fillable", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-004h", + "title": "Cloudflare Email Service outbound -- agents can email external recipients and each other", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005", + "title": "Multi-agent backend (per-agent brains) — agent registry, per-agent DO+Workspace bundle (SOUL.md/MEMORY.md/skills), create+delete agent, n/10 quota, subagent delegation", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": null + }, + { + "id": "L7-005a", + "title": "Multi-agent foundation — per-user Company supervisor DO + agents registry + per-agent DO/Facet keying (userId:agentId) + bundle provisioning (no back-compat)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005b", + "title": "Create + delete agent — agent.create/list/delete oRPC, n/10 quota, full bundle teardown (type-to-confirm), email FK + node binding", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005c", + "title": "Per-agent memory + skills — assemble.ts SOUL.md/MEMORY.md/skills injection (token-budgeted, context-fenced) + per-agent curator + default skill-pack seeding + shared org memory on the supervisor", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005d", + "title": "Frontend multi-agent — real roster (agent.list), New-agent + delete forms, per-agent CopilotKit keying (no remount cross-talk), Mode/Node tabs, ?agent=", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005e", + "title": "Subagents + inter-agent routing — delegate_task (CF child facet via this.subAgent + daemon agent_task over the story tree, ephemeral, hard-capped) + Company supervisor routing", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-005f", + "title": "Per-agent routing end-to-end — route /agui chat + inspector oRPC by agentId to the selected facet + real SOUL.md persona injection (closes the L7-005 dogfood gaps)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-006", + "title": "Migrate agent web shell to CopilotKit v2 (provider + chat + self-managed thread restore) — fixes history-on-reload", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-007", + "title": "Agents-centric navigation IA — collapse top nav to Agents + Audit Log, Settings in the user menu, fold Mission Control into Settings→Nodes, split Email (config→Settings / inbox→agent-shell), encode account-owned vs agent-bound nodes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-008a", + "title": "Semantic memory taxonomy + MemoryManager contract -- codify sources, write policy, and CF run-loop seams", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-008b", + "title": "Direct curated memory tool -- Hermes-style person/org/notes/machine targets with safety guards", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-008c", + "title": "Consolidation lifecycle metadata -- curator state, run reports, and fail-open scheduling", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-008d", + "title": "Skill usage and curator -- provenance sidecar, stale/archive state, and umbrella consolidation dry-run", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L7-008e", + "title": "Memory observability gate -- inspector sources, dropped sections, archive state, and cross-session recall dogfood", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 7.5, + "counts": { + "completed": 1 + }, + "total": 1, + "gate_status": "not_started", + "is_current": false, + "stories": [ + { + "id": "L75-001", + "title": "Landing page redesign — liquid-glass + scroll parallax, auto-company positioning, connectors-first onboarding", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 8, + "counts": { + "completed": 5 + }, + "total": 5, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "L8-001", + "title": "Background review run — alarm-scheduled post-turn self-improvement with beforeToolCall enforcement", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L8-002", + "title": "Cadence counters + review budget — learning effort scales with activity", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L8-003", + "title": "Review prompt pack + capacity-forced consolidation — umbrella skills, anti-capture, over-cap consolidate-now", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L8-004", + "title": "Curator lifecycle states — active/stale/archived with consolidations-vs-prunings reporting", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L8-005", + "title": "Layer 8 gate — agent demonstrably learns a job (umbrella skill authored, recalled, reused)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 9, + "counts": { + "completed": 5 + }, + "total": 5, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "L9-001", + "title": "Company task ledger — company_task/task_run/task_comment/approval tables with atomic checkout", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L9-002", + "title": "Heartbeat wake protocol — trigger paths + seeded company-protocol skill", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L9-003", + "title": "Run supervision — liveness classification, continuation wakes, timeout watchdogs, failure taxonomy", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L9-004", + "title": "Task board + approval cards — company work surface in the dashboard", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L9-005", + "title": "Layer 9a gate — assign/heartbeat/supervise/approve E2E", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 10, + "counts": { + "completed": 5 + }, + "total": 5, + "gate_status": "scripted_passed", + "is_current": false, + "stories": [ + { + "id": "L10-001", + "title": "CompanyContext DO + mount-table dispatcher — Mirage adapter contract over the agent workspace", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L10-002", + "title": "Notion connector — OAuth + scoped database/page-subtree mount", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L10-003", + "title": "Google Drive connector — OAuth + scoped folder mount with per-MIME export", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L10-004", + "title": "Agent integration — mounts in file tools + codemode, PROMPT injection, inspector visibility", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L10-005", + "title": "Layer 10 gate — grounded answers from mounted company context E2E", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 10.5, + "counts": { + "completed": 6 + }, + "total": 6, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "L105-001", + "title": "Unified top-anchored dialog primitive — refactor DialogContent, delete per-dialog positional overrides", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L105-002", + "title": "Company sidebar section + always-present company agent (ensureDefaultAgent backfill)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L105-003", + "title": "Node ↔ agent assignment — one daemon per agent, enforced + manageable", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L105-004", + "title": "Company Overview page (Tier 1) — responsive status cards + infra strip + work summary; work board mobile mode", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L105-005", + "title": "3D office (Tier 2) — code-split three.js isometric scene with live agent-state animations", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L105-006", + "title": "Layer 10.5 gate — deterministic seed for the test user + e2e-test skill scenario + prod dogfood", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 11, + "counts": { + "completed": 6 + }, + "total": 6, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "L11-001", + "title": "Agent purpose one-liner + isCompanyAgent predicate — registry foundation for the COO projection", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L11-002", + "title": "Company-agent read tools — list_agents / list_tasks / get_agent_profile gated by isCompanyAgent", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L11-003", + "title": "Chat-driven delegation — create_task with allowRoot + COO protocol so 'assign X to Y' works end-to-end", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L11-004", + "title": "/company/wiki — durable workspace adapter on CompanyContext with wildcard read ACL and company-agent-only writes", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L11-005", + "title": "Run observability RPC chain — getAgentRunTranscript over agent_run_step + company-wide run feed + files-produced", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L11-006", + "title": "Layer 11 gate — COO control plane + run observability E2E (scripted + prod dogfood)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 11.5, + "counts": { + "completed": 9 + }, + "total": 9, + "gate_status": "passed", + "is_current": false, + "stories": [ + { + "id": "L115-001", + "title": "?view= URL promotion — center views become URL-addressable on /dashboard/agent", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-002", + "title": "Mobile bottom tab bar — portrait-phone entry to Agents / Company / Work / Settings", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-003", + "title": "Sidebar IA regroup — COMPANY group above AGENTS; Coordination dissolves; Skills to the right inspector", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-004", + "title": "Company tabs + Activity — Overview | Activity | Context scaffold; audit folds in; /dashboard/audit redirects", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-005", + "title": "Context tab — connector status + mount create/delete + relocated ACL matrix (deleteMount oRPC included)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-006", + "title": "Trello-style work board — goal lanes, guarded drag (In Progress not droppable), live run chips", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-007", + "title": "Task execution detail — Run pane with transcript replay, live polling, and files produced", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-008", + "title": "AlertDialog top-anchor completion — finish the L105-001 dialog unification", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L115-009", + "title": "Layer 11.5 gate — mobile IA + board + run-pane dogfood (scripted + prod) with calibration capture", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 12, + "counts": { + "completed": 7 + }, + "total": 7, + "gate_status": "scripted_passed", + "is_current": false, + "stories": [ + { + "id": "L12-001", + "title": "Voice foundations spike — env.AI binding, @cloudflare/voice mixin contract, TTS provider decision (binary exit criteria)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-002", + "title": "Voice-shaped facet turn entry point — {threadId, utterance} → text-delta stream with typed markers + per-thread turn latch", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-003", + "title": "Voice ticket — protectedProcedure mint with TTL + per-user concurrent-call cap", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-004", + "title": "VoiceGateway DO — packages/voice core pipeline (mixin + Flux + ticket gate + turn bridge + chosen TTS)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-005", + "title": "Call guardrails + per-stage latency metrics — caps, hangups, quota, unmuted-only ASR", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-006", + "title": "Web voice UI — mic button, call overlay, voice chip (regular agent threads only, desktop-first)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + }, + { + "id": "L12-007", + "title": "Layer 12 gate — voice E2E (scripted + prod dogfood with calibration capture)", + "status": "completed", + "stage": 5, + "exception": null, + "why": null + } + ] + }, + { + "layer": 13, + "counts": { + "completed": 11 + }, + "total": 11, + "gate_status": "not_started", + "is_current": false, + "stories": [ + { + "id": "L13-001", + "title": "Server-side company-agent permanence guard", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The default company agent is a permanent per-account invariant; UI-only deletion hiding is insufficient before hire/formation tools ship." + }, + { + "id": "L13-002", + "title": "Built-in skill packages as skill-creator-validated SKILL.md files", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Every agent (the company agent and future employees) is seeded from the built-in skill pack; the packs must follow a validated, canonical skill structure before new company skills are layered on top." + }, + { + "id": "L13-003", + "title": "Company-agent formation skill and confirmed company brief", + "status": "completed", + "stage": 5, + "exception": null, + "why": "A new account should leave onboarding with a confirmed company brief the agent can use, not an empty default agent." + }, + { + "id": "L13-004", + "title": "Real orgSeedMode company seed from the confirmed brief", + "status": "completed", + "stage": 5, + "exception": null, + "why": "New employee agents must inherit real company context at creation; today buildOrgSeed(company) is a placeholder stub." + }, + { + "id": "L13-005", + "title": "Approval-backed hire_agent over the existing provisioning path", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The company agent should propose an employee design and, after approval, create a fully configured agent — without a parallel agent system." + }, + { + "id": "L13-006", + "title": "inspect_context_freshness over the existing mount warmer", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The company agent should notice when watched /company/wiki or Notion sources changed since the brief was last confirmed — without a new sync platform." + }, + { + "id": "L13-007", + "title": "Layer 13 gate — formation to hire to first task to freshness", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Prove the minimal company-formation-to-hiring loop end to end before expanding into observers, cockpit, or generative UI." + }, + { + "id": "L13-008", + "title": "hire_agent slug normalization and actionable propose errors", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The product-shaped hire loop is a DEAD-END for the most natural roles: a 'customer support agent' makes the model pick slug support/support-lead/customer-support — all rejected by isValidAgentSlug (reserved word + hyphen ban). The model then silently loops to the tool-call cap and NO agent is hired; the user sees only 'Tools ran (5 calls) but the model couldn't produce a final summary'. Dogfood reproduced this twice on prod; it only worked when the operator dictated an explicit valid slug." + }, + { + "id": "L13-011", + "title": "hire_agent input schema robust to model arg-shape fumbles + no byte-exact blueprint re-send on hire", + "status": "completed", + "stage": 5, + "exception": null, + "why": "L13-008 fixed the SLUG dead-end but the natural-language hire STILL dead-ends on prod (re-dogfood 2026-06-16): the model reliably wastes 1-2 of its 5 tool calls per turn on hire_agent Type-validation errors before landing the correct arg shape — it guesses roleSlug (vs slug), skillPack (vs skillPacks[]), firstTask:'' (vs {title,body}), and a FLAT object missing the discriminatedUnion mode + nested blueprint. A clean SSE turn lands by call 3, but a browser turn with longer history blows the 5-call cap → 'Tools ran (5 calls) but the model couldn't produce a final summary'. Reproduced live. PLUS hire mode requires re-sending the BYTE-EXACT approved blueprint or returns blueprint_mismatch — fragile across paraphrase/threads. Net: the headline 'hire a customer support agent' flow is still not reliable." + }, + { + "id": "L13-009", + "title": "Strip company tool-call control tokens from rendered chat", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Company tool-call events render as literal, often-duplicated UPPERCASE text tokens (HIRE_AGENT, FORMATION_START, FORMATION_CONFIRM, INSPECT_CONTEXT_FRESHNESS) each followed by DONE in the user-facing chat — exactly during the first-run formation/hire flow, making the product look broken." + }, + { + "id": "L13-010", + "title": "Surface the hire blueprint summary on the approval card", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The WORK-board pending-approval row for a hire shows only 'HIRE / @DEFAULT' — no who/slug/first-task — so the operator approves a hire blind. The blueprint is already stored on the approval row; it just isn't surfaced." + } + ] + }, + { + "layer": 14, + "counts": { + "deferred": 7 + }, + "total": 7, + "gate_status": "deferred", + "is_current": false, + "stories": [ + { + "id": "L14-001", + "title": "Typed company-fact store and provenance model", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "The company agent needs canonical company context before it can design employees or steer the company." + }, + { + "id": "L14-002", + "title": "Connector observer registry and event ingestion", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "The company context layer must notice when humans keep changing Notion/wiki sources after initial onboarding." + }, + { + "id": "L14-003", + "title": "Context-review candidate loop for stale or new company facts", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "Long-lived company memory needs a review loop that turns changing source data into proposed updates without silently mutating canonical facts." + }, + { + "id": "L14-004", + "title": "FDE readiness score and rollout cockpit projections", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "Operators and FDEs need a cockpit that proves whether the AI-native company rollout is ready, moving, and producing value." + }, + { + "id": "L14-005", + "title": "Field-learning loop for reusable company-agent playbooks", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "Looplia should turn repeated AI-company transformations into reusable blueprint templates and product learnings." + }, + { + "id": "L14-006", + "title": "Full hire provisioning — budget-policy modes and deprovisioning lifecycle", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "A company agent should be able to create the right employee agent fully configured, while preserving human approval and audit." + }, + { + "id": "L14-007", + "title": "Layer 14 gate — FDE platform-deepening E2E", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "Prove the company agent can bootstrap company context, hire an employee agent, observe context drift, and show rollout value." + } + ] + }, + { + "layer": 14.5, + "counts": { + "deferred": 2 + }, + "total": 2, + "gate_status": "deferred", + "is_current": false, + "stories": [ + { + "id": "L145-001", + "title": "Voice-first generative company interaction canvas", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "The company agent should turn spoken or typed operating intent into a live company dashboard the user can edit, approve, and monitor." + }, + { + "id": "L145-002", + "title": "Layer 14.5 gate — voice/generated dashboard E2E", + "status": "deferred", + "stage": 1, + "exception": "deferred", + "why": "Prove the company agent's primary interface is a voice-steered generated operating surface, not only a chatbot." + } + ] + }, + { + "layer": 15, + "counts": { + "completed": 7 + }, + "total": 7, + "gate_status": null, + "is_current": false, + "stories": [ + { + "id": "L15-001", + "title": "WorkspaceSkillProvider — official SkillProvider over the per-agent /skills (pure)", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Foundation for adopting the Agents SDK's official progressive-disclosure skills mechanism (SkillProvider + load_context). Today Looplia rolls its own keyword-push full-body injection in memory/assemble.ts — it never shows the model a skill CATALOG and gives it no tool to load a skill on demand, so the model can't discover existing skills (this is why the company agent re-invented a malformed agent-hiring skill on prod). This story adds the provider only — the read/load primitive everything else builds on — with zero production wiring, so it ships risk-free." + }, + { + "id": "L15-002", + "title": "Skill catalog injection + pinned-only body injection (read side)", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The user-visible behavior flip: the model stops being force-fed top-5 keyword-scored skill BODIES and instead always sees a compact CATALOG (name+description) of its unpinned skills, plus the full bodies of its small pinned set. This is what makes progressive disclosure real from the model's side and frees the ~1500-token memory budget that skill bodies were consuming. Decision (locked with user): pinned skills (company-protocol, company-formation, company-coo) stay always-on full-body; unpinned become catalog + on-demand load." + }, + { + "id": "L15-003", + "title": "load_context / unload_context tools (model-invoked skill loading)", + "status": "completed", + "stage": 5, + "exception": null, + "why": "The Level-2 half of progressive disclosure and the riskiest integration — give the model a tool to load a full skill body on demand (and reclaim it). This is what the SDK's load_context does; without it the catalog is just advisory. Isolated as its own slice so the catalog (L15-002) can be dogfooded before the model can act on it." + }, + { + "id": "L15-004", + "title": "Skill telemetry + curator lifecycle continuity under the new access pattern", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Keep the /skills/_usage.json lifecycle (provenance, view/use counts, stale→archive, pinned bypass) honest after skills move from keyword-injection to catalog+load. Without this, the curator's stale/archive signals decay (it can no longer see a skill being 'viewed' via injection) and archived skills could leak back into the catalog." + }, + { + "id": "L15-005", + "title": "Skill-write hardening — route /skills writes through the provider (closes the malformed-skill root cause)", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Closes Issue-1's root cause. On prod (test2@) the company agent self-authored TWO malformed skills (/skills/agent-hiring + /skills/agent_hiring — no YAML frontmatter, duplicate kebab/snake naming, one teaching the stale pre-L13-011 hire flow) via the generic write/edit file tools. manage_memory forbids /skills writes but createWorkspaceTools (write/edit) does not, and nothing validates SKILL.md frontmatter or dedups names. This violates L13's own verification contract ('canonical skill-creator-validated SKILL.md packages, name+description frontmatter')." + }, + { + "id": "L15-006", + "title": "Seed a correct pinned agent-hiring skill into the company agent", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Closes the vacuum that caused Issue-1. Hiring is a core company-agent function (hire_agent) yet there is NO seeded hiring skill (unlike company-coo / company-formation), so the model improvised a malformed one teaching the stale pre-L13-011 flow. Ship a canonical, pinned, company-only agent-hiring SKILL.md teaching the CORRECT L13-011 flow (propose → approval → {mode:hire, approvalId} alone, no byte-exact blueprint re-send)." + }, + { + "id": "L15-007", + "title": "Migration — detect + archive malformed (frontmatter-less) skills on existing agents", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Remediates the malformed skills already on prod (test2@ has /skills/agent-hiring + /skills/agent_hiring with no frontmatter) — and any other agent that freelanced one — rather than a one-off manual delete. The inspector RPC is read-only, so cleanup needs a write/maintenance path; a migration that archives frontmatter-less skills generalizes across all agents and is recoverable (archive-only, never hard-delete)." + } + ] + }, + { + "layer": 16, + "counts": { + "completed": 3 + }, + "total": 3, + "gate_status": null, + "is_current": false, + "stories": [ + { + "id": "L16-001", + "title": "Agent inspector: center drill-down modal + IA (drop Mode tab, add Agent tab with identity + read-only SOUL.md + canonical memory)", + "status": "completed", + "stage": 5, + "exception": null, + "why": "Inspector design review (2026-06-16/17) found the right inspector shows misleading and hard-to-read state. (1) Files tab previews file content INLINE at the bottom of the narrow sidebar (FilePreview) — a
 in ~300px is unreadable. (2) The 'Mode' tab exposes DEFAULT_PERSONA.systemPrompt: a hardcoded baseline mirrored in the web bundle, IDENTICAL for every agent — it reads as 'this agent's prompt' but is neither per-agent nor real. The true per-agent identity contract (SOUL.md) is never shown. (3) The Memory tab special-cases a legacy /memory/profile.md block AND separately lists notes/person/org in semantic sections — re-introducing the exact profile-vs-MEMORY confusion the canonical taxonomy (taxonomy.ts:22-26) was built to resolve. Fix: move all drill-downs into a readable center modal; drop the Mode tab; fold identity into a renamed 'Agent' tab that leads with identity then shows the REAL read-only SOUL.md; render the memory layer by canonical taxonomy with no legacy blocks."
+        },
+        {
+          "id": "L16-002",
+          "title": "Skills tab: wire real per-agent skills (deriveAgentSkills) — drop the mock library",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The inspector Skills tab (and the center Skills view) render MOCK_SKILLS (shell-ops/git-flow/… from _fixtures.ts) — pure placeholder that does NOT reflect any agent's real capabilities. Real skill state is fully derivable from data the inspector already fetches, so the mock is both wrong and unnecessary. Show the agent's REAL pinned (always-on) + active + archived skills, clickable to read the SKILL.md."
+        },
+        {
+          "id": "L16-003",
+          "title": "Sunset legacy /memory/profile.md + /MEMORY.md from the memory pipeline",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "profile.md and MEMORY.md are LEGACY files the canonical taxonomy (L7-008a) superseded with /memory/people/.md (person) and /memory/notes.md (notes); taxonomy.ts:22-26 documents that the three historically blurred 'who is the agent / who is the user / durable notes'. They are still read in-place by assemble.ts and surfaced by getAgentMemory.profile, which keeps the confusion alive in both the prompt and the API. Retire them so each fact has exactly one canonical home. Owner confirmed (2026-06-17) the service is PRE-LAUNCH with no real-user data, so the design-D5 'never delete legacy' safety (which existed only to avoid losing live memory) does not apply — a content-forward migration is optional, not a gate."
+        }
+      ]
+    },
+    {
+      "layer": 17,
+      "counts": {
+        "completed": 2
+      },
+      "total": 2,
+      "gate_status": null,
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L17-001",
+          "title": "Remove the memory-curation default skill — memory is a first-class tool (manage_memory) + curator",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The default skill pack ships a `memory-curation` SKILL.md teaching the agent how to tidy its memory — but durable memory is now a first-class TOOL (`manage_memory`, L7-008b) whose own description already carries the save/don't-save policy (stable facts yes; task progress/TODOs/dumps no), and a background curator consolidates turns automatically. The prose skill is therefore redundant. Worse, after L16-003 retired /MEMORY.md + /memory/profile.md, the skill body is actively STALE — it still tells the agent its memory 'lives in /MEMORY.md (index), /memory/profile.md (user facts)', the exact paths manage_memory now FORBIDS. Remove the skill so the only guidance on durable memory is the canonical tool surface. shell-usage / email-triage / task-decomposition stay as on-demand catalog skills (task-decomposition is the on-demand home for generic planning; company task-board decomposition stays in the always-on company-protocol via create_subtask)."
+        },
+        {
+          "id": "L17-002",
+          "title": "Fix: New-Agent dialog 'Create with defaults' silently no-ops (no create RPC, no agent)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "BUG found in prod dogfood (2026-06-17, test@looplia.run): in the New-Agent dialog, after filling name+slug with the 'Create with defaults' button ENABLED, clicking it closes the dialog but fires NO network request and creates NO agent (reproduced 3x; agent-browser `network requests` shows nothing on click; roster stays 2/10; no error toast). Creating an agent from the UI is a core path — it is currently broken (the existing agents on the account were created via the agent-driven hire_agent flow, not this dialog, which is why it went unnoticed). This also BLOCKS live verification of L17-001 (a fresh agent is needed to confirm the new 7-skill seed)."
+        }
+      ]
+    },
+    {
+      "layer": 18,
+      "counts": {
+        "completed": 8
+      },
+      "total": 8,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L18-001",
+          "title": "company_north_star state + fixed-id anchor task + supervisor north-star RPC",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The autonomous loop needs a durable, steerable target. Adds the company_north_star record (statement + objectives + success_criteria) on the LoopliaCompany supervisor SQLite — named apart from the work ledger's per-task goal_id so the two 'goal' concepts never collide — plus the fixed-id 'pursue north star' anchor task every heartbeat tick hangs on (a stable id, NOT a fresh UUID, so the unique-active-run coalescing survives anchor recreation). Foundation: without it L18-003 has nothing to pursue and there is no human-writable goal surface."
+        },
+        {
+          "id": "L18-002",
+          "title": "companyAutopilot oRPC router (north-star + loop reads/writes) + protocol wire types",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The human steering panel (L18-005) needs a typed read/write surface to the supervisor's north-star + loop config. Adds the oRPC router and shared wire types so the web app can set the north star, toggle/configure the loop, and list recent heartbeats."
+        },
+        {
+          "id": "L18-003",
+          "title": "Opt-in heartbeat scheduler — companyHeartbeat + #syncHeartbeatSchedule + loop config + MAX_TICKS",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The periodic self-trigger — the actual autonomous main loop. A supervisor-scheduled tick mints ONE goal-pursuit run for the default agent through the EXISTING reactive wake pipeline when the loop is enabled, not paused, and under the MAX_TICKS cap. Off by default; the human enables it and picks an interval. This is what makes the company act without an inbound event."
+        },
+        {
+          "id": "L18-004",
+          "title": "buildNorthStarTrigger + runGoalPursuitTurn facet RPC + anchor wake branch + goal context",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Turns a bare heartbeat into goal-seeking. On the anchor task the supervisor assembles the north star + current board/roster/freshness summary and seeds a Hermes /goal-framed turn: 'does the current state move us toward the north star? take the single highest-leverage next action.' A cycle counts as productive only when it DELEGATES to a named worker agent or raises an approval (serves the trust-through-delegation contract), not when the company agent talks to itself."
+        },
+        {
+          "id": "L18-005",
+          "title": "Autopilot tab on /dashboard/company — north-star editor + loop controls + heartbeats feed",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The human steering surface. A new Autopilot tab lets the operator set the north star (statement + objectives + success criteria), enable/disable the loop, choose the interval, pause/resume, and see a recent-heartbeats feed of what each cycle did. This is how a human aims and steers the autonomous company."
+        },
+        {
+          "id": "L18-006",
+          "title": "Layer 18 gate — autonomous loop E2E (scripted + prod dogfood)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves the autonomous loop works end-to-end and safely before L18.5 spend governance: set a north star, enable the loop, observe a DELEGATING goal-pursuit cycle, and confirm pause/disable bound it."
+        },
+        {
+          "id": "L18-007",
+          "title": "Supervisor periodic-alarm self-heal + tick fan-out hardening",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Phase 1 of the loop-trigger fix. The supervisor's periodic DO-alarm chain wedges on an idle/evicted DO (running=1 rows never re-arm; deploy-mid-alarm burns the 6-retry budget per cloudflare/agents#1730), so companyHeartbeat (and the always-on ticks) silently die. A self-heal probe re-arms a dead alarm whenever the DO is woken; isolating the tick fan-out stops one throw from poisoning the chain."
+        },
+        {
+          "id": "L18-008",
+          "title": "Cron Trigger + D1 registry — liveness-independent company-heartbeat trigger",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Phase 2 (the robust fix). A Worker Cron Trigger (every 1 min) reads a D1 registry of opted-in users and RPCs each due tenant's companyHeartbeat() — independent of DO liveness, so it cannot be wedged like the DO alarm. This is what actually makes the autonomous loop fire in prod."
+        }
+      ]
+    },
+    {
+      "layer": 18.5,
+      "counts": {
+        "completed": 4
+      },
+      "total": 4,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L185-001",
+          "title": "Token/cost capture (run-stream usage) + company_cost_ledger + recordRunCost RPC",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "You cannot bound spend you do not measure. Captures the model step's token usage (today DISCARDED in run-stream.ts), threads it through the run loop, and records per-run cost on the supervisor — the substrate for the budget hard-stop. Charges all autonomous spend, not just goal ticks."
+        },
+        {
+          "id": "L185-002",
+          "title": "Budget config + hard-stop (#hardStopOnBudget) + pre-tick/post-charge/in-loop checks",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The anti-overspend control. A per-period budget the operator sets; when period spend crosses it the loop HARD-STOPS — auto-pauses (paused_reason=budget) and raises one budget approval card. Distinct from L18's anti-runaway loop controls."
+        },
+        {
+          "id": "L185-003",
+          "title": "Budget oRPC + Autopilot tab budget UI (live spend bar) + approvals view",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Makes spend visible and steerable: the operator sets the budget, watches a live spend bar, and resolves the budget approval card when the loop auto-pauses."
+        },
+        {
+          "id": "L185-004",
+          "title": "Layer 18.5 gate — spend governance E2E (scripted + prod dogfood)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves the budget hard-stop actually bounds autonomous spend: watch spend climb, cross the budget, see the loop auto-pause + raise an approval, then resume."
+        }
+      ]
+    },
+    {
+      "layer": 19,
+      "counts": {
+        "completed": 15
+      },
+      "total": 15,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L19-001",
+          "title": "Goal-linked, queryable, idempotent tickets",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The deterministic backbone of coordination: link goal-pursuit-delegated tasks to the north-star anchor so 'the goal's work' is a real set, make the ledger goal-queryable, and make create_task idempotent so a duplicate task literally cannot be created — the backstop that guarantees the L18 re-delegation bug can't recur even if the model misjudges."
+        },
+        {
+          "id": "L19-002",
+          "title": "Shared company operating-state (write + curation)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The memory-driven coordination layer: a durable plan/decision-log in /company/wiki/company-plan.md plus a concise, bounded, REGENERATED-each-tick 'operating-state' line auto-injected into every agent's turn via the existing shared-org channel. This is how the company agent (next tick) and employees share situational awareness without prompt luck."
+        },
+        {
+          "id": "L19-003",
+          "title": "Progressive-disclosure wiring",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Enforces the anti-context-rot contract at the injection layer: the durable plan is surfaced only as a POINTER (the existing mount-prompt pattern), the concise operating-state lives inside the bounded shared-org budget, and the full plan is loaded on-demand — so the shared memory never bloats any agent's per-turn context."
+        },
+        {
+          "id": "L19-004",
+          "title": "Goal-pursuit reconciliation rewrite",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Turns goal-pursuit from 'must delegate every tick' (the behavior that caused the duplicate-delegation) into a read -> reconcile -> act-on-gaps -> record loop, so the company agent only delegates genuinely uncovered work and recognizes completion."
+        },
+        {
+          "id": "L19-005",
+          "title": "Employee-side shared awareness",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Closes the loop on shared coordination: employee agents see the concise company operating-state in their per-turn memory (so they don't act against stale assumptions) and can load the full plan on demand."
+        },
+        {
+          "id": "L19-006",
+          "title": "Layer 19 gate — coordinated goal-pursuit E2E (scripted + prod re-dogfood)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves coordination is now a property of shared state: the loop no longer re-delegates, recognizes completion, and the shared memory stays bounded (no context rot)."
+        },
+        {
+          "id": "FIX-HIRE-001",
+          "title": "Idempotent hire lifecycle — autonomous loop spams duplicate hires and never provisions the approved one",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG found in the 2026-06-18 L19 companyAgent re-dogfood (clean account, creativewriter deleted to force the HIRE path). Over ~13 heartbeat ticks the autonomous loop minted 13 DUPLICATE 'hire' approvals for the same slug, never provisioned the approved hire (consumedAt stayed null), created ZERO goal tasks, and delivered nothing. Same duplicate-work class L19 fixed for TASKS, but the HIRE lifecycle (propose->approve->provision) is neither idempotent nor self-coordinating. Without this, any north star that requires hiring a new agent diverges into hire-spam instead of progressing."
+        },
+        {
+          "id": "FIX-COO-MAILBOX-001",
+          "title": "Company agent (COO/default Looplia) has no mailbox — any email-delivery goal dead-ends in blocked",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG found in the 2026-06-24 journeys 13-18 autonomy dogfood (clean account, creative-writing north star that requires emailing a deliverable). The COO (default agent 'Looplia') WROTE the episode but could not send it — its own task comment: 'the company agent (Looplia) has no mailbox configured ... list_mailboxes returns empty'. Employee agents auto-provision a default mailbox on agent.create; the backfilled company/default agent never gets one, so the canonical keyed task sticks in BLOCKED and the loop improvises by dumping the work on whatever mailboxed agent is idle (see FIX-COO-DELEGATION-001). Any north star whose deliverable is an email is structurally un-completable by the COO."
+        },
+        {
+          "id": "FIX-COO-DELEGATION-001",
+          "title": "COO mis-delegates via capability-blind reuse — assigns writing to the Reviewer (idle+has-mailbox), collapsing producer and reviewer",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG found in the 2026-06-24 journeys 13-18 autonomy dogfood. Blocked on sending (FIX-COO-MAILBOX-001), the COO did NOT hire a writer — it delegated the WRITING+SENDING to the Reviewer agent because it was 'idle and has the nftasasc-reviewer email binding'. The reuse heuristic keys on has-mailbox + idle, NOT on role/capability fit. Result: producer and reviewer collapse into one agent, the Reviewer emails ITSELF (Ep1/Ep2 from=to=nftasasc-reviewer in both sent and inbox), and independent acceptance review (Journey 16, the 驗收 half) becomes impossible."
+        },
+        {
+          "id": "FIX-DEDUP-001",
+          "title": "Idempotency/dedup breaks across the delegate boundary — delegated subtasks get key:null under a different goalId (L19 task-dedup regression)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG found in the 2026-06-24 journeys 13-18 autonomy dogfood. L19 made goal-linked TASK creation idempotent on a stable key (goal::) — but Episode 1 appeared TWICE: the canonical task (key goal:north-star-anchor:write and email episode 1..., assignee=default, BLOCKED) AND a duplicate with key:null under a different parent (assignee=Reviewer, DONE); Episode 2 landed under an unrelated goalId with key:null. The duplicate-work class L19 was meant to eliminate re-enters through the agent-tool delegate path. Owner note: this was supposedly solved before — find the ROOT CAUSE."
+        },
+        {
+          "id": "FIX-LOOP-WEDGE-001",
+          "title": "Autonomous loop wedges on a stuck status=running heartbeat — one-active-run invariant + no reaper halts all ticks silently",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG (HEADLINE) found in the 2026-06-24 journeys 13-18 autonomy dogfood. After 4 ticks the loop stopped advancing: goal-pursuit heartbeat attempt 13 hung in status=running (liveness null) and never completed (>28 min stale). The one-active-run-per-user invariant (agent-run-store.ts getActiveRunId) then makes every subsequent cron tick a no-op, so loop/get reports enabled:true paused:false while ticksUsed is frozen and NO error/notice surfaces to the owner. The fiber visibly degenerated first (attempts 8-10 plan_only, 11-12 empty_response, 13 hung). No reaper failed/timed-out the hung run to release the slot. An owner who 'sets a goal and walks away' returns to a company that silently died after ~4 ticks. Likely same family as feedback_do_periodic_alarm_unreliable (idle-DO alarm) but at the run level."
+        },
+        {
+          "id": "FIX-EMAIL-ADDR-001",
+          "title": "Agent-to-agent email fails because sibling mailboxes are surfaced as bare aliases (no @looplia.run) — recipients bounce or silently lose to a guessed @localhost",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PROD BUG found in the 2026-06-25 journeys 13-18 RE-dogfood (after FIX-COO-* shipped). Now that delegation works (producer != reviewer, FIX-COO-DELEGATION-001), agent->agent email is on the critical path — and it fails. The COO was asked to email a deliverable to 'nftasasc-reviewer' (a bare alias, as surfaced in the roster/north-star) and addressed it to nftasasc-reviewer@localhost; the message showed status=delivered but NEVER reached the reviewer (reviewer inbox empty). Proven decisively with three forms of the SAME recipient: bare 'nftasasc-reviewer' -> BOUNCED (trash); 'nftasasc-reviewer@localhost' (model-guessed domain) -> phantom 'delivered' but lost; 'nftasasc-reviewer@looplia.run' (correct) -> delivered into the reviewer inbox. The email SERVICE is healthy (internal round-trip + external gmail both confirmed) — the defect is that agents are never given the canonical @looplia.run address and the send path does not canonicalize/validate an internal recipient."
+        },
+        {
+          "id": "FIX-DELIVERY-GATE-001",
+          "title": "Email-delivery tasks are marked done without confirming delivery — loop trusts a synchronous/absent send instead of the email service's delivered/bounced signal",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "OWNER-DIRECTED finding from the 2026-06-25 re-dogfood: 'we should have a mechanism to confirm via the email service whether a message was delivered before confirming the work is complete.' Two symptoms: (a) a 'compose AND email the Founder Update' goal was decomposed to a single 'Compose Founder Update paragraph' task marked DONE while NO email was ever sent (writer + COO sent folders had no such message); (b) the @localhost episode sends were recorded status=delivered (phantom) and their tasks completed on that. Net: the autonomous company reports success on undelivered work — the core coherence risk for L18/L19 autonomy."
+        },
+        {
+          "id": "FIX-DEDUP-002",
+          "title": "FIX-DEDUP-001 is partial — delegated subtasks still get key:null under a fresh sub-goalId (the agent delegate path escapes the createTask key chokepoint)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Re-dogfood (2026-06-25) follow-up to FIX-DEDUP-001 (PR #213). The createTask #resolveAnchorKey chokepoint stamps stable keys for tasks under the north-star anchor (Phase 1: 3 episodes all carried goal:north-star-anchor:... keys, no dupes across 3 ticks — CONFIRMED). But when the COO DELEGATED (Phase 2), the resulting 'Compose Founder Update paragraph' task came back with key:null under a FRESH sub-goalId (58349afb...), not the anchor — the same keyless shape FIX-DEDUP-001 set out to eliminate. It did not duplicate this round only because the task completed within a single tick; the protection is absent on the delegate-spawns-subgoal path, so a multi-tick delegated unit can still duplicate."
+        },
+        {
+          "id": "FIX-DEDUP-003",
+          "title": "Re-dogfood: duplicate Episode 1 persists on the delegate path — the same logical task is minted via BOTH the delegate root (delegate: key) AND goal-pursuit decomposition (goal: key), and the per-namespace idempotency check never reconciles the two namespaces",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Re-dogfood (2026-06-25, prod) of FIX-DEDUP-002 (PR #218). Forced-hire phase: the COO correctly hired a dedicated writer and delegated (producer != reviewer), and FIX-DEDUP-002's stable delegate: key DID ship — but the original L19 'duplicate Episode 1' symptom REPRODUCED. The reviewer received 3x 'Episode 1' emails and 0x 'Episode 2'; the loop burned ticks re-producing Episode 1 and never advanced (a progress block, not cosmetic). Root cause is a DIFFERENT, cross-path gap than FIX-DEDUP-002 closed: the same episode was created twice — once via the explicit delegate root (key delegate:default:...; goalId=self; parent=null) and once via the heartbeat's goal-pursuit decomposition (key goal:north-star-anchor:...; parent=north-star-anchor). Idempotency is checked per-namespace, so delegate:* and goal:* never dedup each other."
+        }
+      ]
+    },
+    {
+      "layer": 20,
+      "counts": {
+        "completed": 4
+      },
+      "total": 4,
+      "gate_status": "completed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L20-001",
+          "title": "OKF-conformant shared/company knowledge layer",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Makes Looplia's shared/company knowledge a valid Open Knowledge Format (OKF v0.1) bundle without changing the runtime memory model — the prerequisite for portability. The shared layer Looplia already writes (L19-002 /org/company-state.md + /company/wiki/company-plan.md, L19-003 progressive disclosure) is reshaped to OKF's primitives so any OKF consumer can read it."
+        },
+        {
+          "id": "L20-002",
+          "title": "OKF export — portable company knowledge bundle",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The operator can take their company knowledge OUT — a downloadable/servable OKF-conformant bundle renderable by any OKF consumer (Google's Knowledge Catalog, the spec's static HTML visualizer). No lock-in; the knowledge is portable."
+        },
+        {
+          "id": "L20-003",
+          "title": "OKF import connector — external knowledge as company-context",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The operator can bring external knowledge IN — drop an OKF bundle (a data catalog, runbooks, metric definitions) and have agents read it as company-context. A new connector beside the L10 Notion/Drive connectors, but on an open standard so any OKF producer's output works."
+        },
+        {
+          "id": "L20-004",
+          "title": "Layer 20 gate — OKF conformance + round-trip + interop (scripted + dogfood)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves Looplia genuinely interoperates with the OKF ecosystem: produced bundles conform, round-trip is lossless, and an external bundle is consumable."
+        }
+      ]
+    },
+    {
+      "layer": 21,
+      "counts": {
+        "completed": 6
+      },
+      "total": 6,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L21-001",
+          "title": "Capture per-step model reasoning (runs) and expose it in the transcript",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Makes the agent's THINKING visible per step — the core of a trajectory log (think -> act). Captures the model's reasoning/extended-thinking parts that today are dropped (only final text + tool calls are kept), as a backward-compatible optional field on the existing run/chat transcript stores."
+        },
+        {
+          "id": "L21-002",
+          "title": "Unified per-agent trajectory RPCs: trajectory.list + trajectory.detail",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The data layer for the new Main-Loop view: ONE per-agent timeline merging autonomous/heartbeat/work/delegated RUNS (agent_run_step) with CHAT turns (assistant_messages), newest-first, as an additive read-side aggregation (no destructive migration). Aggregated row -> on-demand detail."
+        },
+        {
+          "id": "L21-005",
+          "title": "Company page cockpit: single #general chat + moved surfaces + Company Vision panel",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "One place for humans to talk to the whole company (a single #general channel) plus the operating surfaces and a prominent Company Vision panel to set/steer the north star. v1 routes every message to the company agent Looplia (front-desk); the @mention-to-an-employee and agents-meeting upgrade is deferred (Layer 22). Reuses the existing chat + autopilot stacks; no backend dependency."
+        },
+        {
+          "id": "L21-003",
+          "title": "Agents page: per-agent trajectory view + detail modal",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The new Main-Loop UI: an agent's aggregated trajectory rows (think -> act) that open a modal with the full step detail (reasoning + tool calls + files), reusing the existing RunTranscript renderer."
+        },
+        {
+          "id": "L21-004",
+          "title": "Agents page IA: sidebar -> Company / Agent / Settings; center = trajectory; remove chat",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The autonomy-first IA: the left sidebar collapses to exactly Company / Agent / Settings, the per-agent center defaults to the trajectory log (no chat), and a foreign/missing selection falls back cleanly."
+        },
+        {
+          "id": "L21-006",
+          "title": "Layer 21 gate — trajectory aggregation + reasoning (scripted) + cockpit dogfood",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves the autonomy-first surface works end-to-end: the unified trajectory merges runs + chat with reasoning, and the moved #general chat + cockpit behave on prod."
+        }
+      ]
+    },
+    {
+      "layer": 22,
+      "counts": {
+        "deferred": 1
+      },
+      "total": 1,
+      "gate_status": null,
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L22-001",
+          "title": "Direct human @mention routing to one named employee",
+          "status": "deferred",
+          "stage": 1,
+          "exception": "deferred",
+          "why": "Lets a human steer one named employee directly while preserving the COO-led autonomous operating model. The former free-form agent-meeting scope is superseded by Layer 36 typed durable deliberation."
+        }
+      ]
+    },
+    {
+      "layer": 23,
+      "counts": {
+        "completed": 12
+      },
+      "total": 12,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L23-000",
+          "title": "Persistent shell layout route + COO chat hoist (structural refactor, no visual change)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PRECURSOR REFACTOR that makes the chat-non-remount property EXIST before the redesign builds on it. Today the COO chat provider is buried inside company.tsx (GeneralTab -> CompanyChat -> AgentChatProvider, behind ?tab=general), and /dashboard/agent + /dashboard/company are SIBLING routes that fully unmount on a switch — so the chat is destroyed on a mode switch and L23-001 cannot fix it by 'generalizing agent-shell.tsx'. This story restructures routing into ONE always-mounted shell and hoists the chat provider above the mode boundary. NO visual or copy change — pure structure."
+        },
+        {
+          "id": "L23-001",
+          "title": "Unified app shell + sidebar-top mode switcher (Company/Agents)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The keystone of the redesign: ONE full-bleed app shell replaces the two divergent pages. Generalizes agent-shell.tsx into a shared AppShell and adds a vertical sidebar-TOP MODE LIST (Company/Agents, ChatGPT/Claude pattern) that switches the center surface; removes the top horizontal AGENTS/COMPANY nav; Settings moves to the sidebar footer. The COO chat provider + shell live ABOVE the mode-swap boundary so switching modes never remounts the chat (L7-006)."
+        },
+        {
+          "id": "L23-002",
+          "title": "Company mode: surfaces as sidebar items + merged Mission surface",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Company mode inside the unified shell: the former Company tabs become sidebar items (Chat / Mission / Overview / Context / Activity) rendered full-bleed into the shell center (dropping the centered max-w-7xl, grid-bg, prose header, tab strip). The duplicate VISION + AUTOPILOT tabs MERGE into ONE Mission surface (goal + loop controls). The chat is reframed as 'Chat (Looplia · COO)' — the default Company surface, no #general wording."
+        },
+        {
+          "id": "L23-003",
+          "title": "Agents mode: trajectory polish (reasoning expanded, two-line rows, live streaming)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Applies the Layer 21.5 ux-flow calibration to the Agents-mode trajectory: per-step REASONING expanded by default in the detail modal (D2); TWO-LINE trajectory rows with a derived summary + a faint reasoning preview, and a fix for the unhelpful 'schedule' run summary (D3); LIVE runs auto-surface to the top and stream their reasoning/tool calls in real time (D7)."
+        },
+        {
+          "id": "L23-004",
+          "title": "COO set_company_mission tool + Mission single source of truth",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The backend core of the COO model (fixes the L21 dogfood incoherence). Looplia (the COO) gets a tool — set_company_mission — to WRITE the company north star + objectives to the Mission single source of truth from within the chat, so the COO can persist the setup it figures out WITH the CEO. The autopilot north star and the company-setup goal become ONE record that the chat context AND the autonomous heartbeat both read — so asking the COO 'what's our north star?' answers correctly."
+        },
+        {
+          "id": "L23-005",
+          "title": "Visual unification + mobile/responsive pass",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The redesign lands as ONE coherent visual language and works on a phone. Unifies the header/background/spacing/typography across both modes (no leftover centered/grid-bg/tab-strip styling) and adds the mobile patterns: sidebar (with its mode list) collapses to a drawer, surfaces become stacked cards, and the detail modal opens as a full-screen sheet (D6)."
+        },
+        {
+          "id": "L23-006",
+          "title": "Layer 23 gate — unified shell + COO Mission SSOT (scripted + dogfood)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves the redesign: the COO writes the Mission single source of truth from chat (and chat + heartbeat read it), the mode switch never remounts the chat, and the unified visual language holds on desktop + mobile."
+        },
+        {
+          "id": "L23-007",
+          "title": "COO chat: restore voice + rename surface to 'Talk to Looplia'",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Two CEO dogfood findings on the shipped redesign. (1) BUG/regression: the voice (mic) affordance vanished from the chat — it is not lost, just GATED OFF (company-chat.tsx hardcodes voiceEligible={false}); the whole voice stack (mic button, useVoiceCall, CallOverlay, voice-surface gating, the voice DO + ASR/TTS adapters + voice_usage ledger) is 100% intact, so restoring it is a pure gating fix. (2) COPY: the COO chat surface still reads 'Chat (Looplia · COO)'; the CEO wants the friendlier 'Talk to Looplia' (drop the parenthetical role)."
+        },
+        {
+          "id": "L23-008",
+          "title": "Trajectory detail modal: scrollable body + responsive (run-detail clips)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "CEO dogfood finding: opening a trajectory entry's detail modal shows content that needs to scroll but cannot — the run-detail body (the merged TranscriptPane) has NO max-height/overflow, so a long transcript grows past the dialog and clips off-viewport (worse on mobile where the modal is full-screen and the header isn't accounted for). The chat-detail body already scrolls correctly; the run-detail body does not. Inconsistent + broken for real (long) runs."
+        },
+        {
+          "id": "L23-009",
+          "title": "Sidebar visual unification — Company surfaces ≡ Agents roster (one style)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "CEO dogfood finding: the collapsible left sidebar looks 'completely different' between Company and Agents modes — yet it is the SAME LeftSidebar component rendering two divergent item styles. Company surface rows = rounded button + cobalt left-accent bar + sidebar-accent tint on active (the captured Direction B 'Studio' calibration); Agent roster items = no radius, tight px-1 py-1, muted bg, NO accent bar, bold-uppercase 11px. Switching modes feels like two apps. This is an implementation drift from the EXISTING visual-design calibration, not a new calibration."
+        },
+        {
+          "id": "L23-010",
+          "title": "Responsive layout pass across both shells (company + agents)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "CEO dogfood finding: 'although we use a left sidebar, the whole site is NOT responsive.' L23-005's visual/mobile pass left real gaps — hardcoded desktop widths (w-72/w-80), no min-w-0 truncation on flex children, breadcrumbs that overflow instead of truncating, an inconsistent center padding strategy, and an all-or-nothing sidebar (full drawer or hidden, no graceful narrow-screen behavior). The CEO asked for a COMPLETE UI-layout review + fix of company/agent responsive consistency. This is the comprehensive responsive sweep."
+        },
+        {
+          "id": "L23-011",
+          "title": "COO chat survives Company↔Agents switch (transcript + draft persistence)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "CEO re-dogfood (2026-06-24) of the shipped L23 redesign found the BLOCKING gate item (23.1) actually FAILS once real messages are in play: after a Company↔Agents mode switch the COO chat reverts to its seed snapshot and DROPS every message sent that session (rows stay persisted server-side, recovered only on a full reload), and the composer draft is lost too. The L23-000 provider hoist was necessary but NOT sufficient — the chat VIEW unmounted with the company route."
+        }
+      ]
+    },
+    {
+      "layer": 24,
+      "counts": {
+        "completed": 7
+      },
+      "total": 7,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L24-001",
+          "title": "json-render substrate + render_ui channel (Talk-to-Looplia generative UI foundation)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The foundation every inline card stands on. Adopt Vercel Labs json-render (@json-render/core + @json-render/react): a Looplia CATALOG (whitelisted components + actions + Zod props) + REGISTRY (React impls), an agent->UI channel via a render_ui tool whose arg is a json-render spec, a chat render bridge that detects a render_ui tool call and renders the spec via the json-render Renderer (+ SpecStream streaming) INSTEAD of the inert GenericToolCard, and catalog.prompt() appended to Looplia's system prompt so the model knows what it can render. Ships with an empty/trivial catalog (no real cards yet) to prove the pipeline end-to-end. Per docs/research-note/17-generative-ui-chat-spine.md."
+        },
+        {
+          "id": "L24-002",
+          "title": "HireApprovalCard component + resolve_approval out-of-band action",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The first real generative card and the reusable approval primitive. A HireApprovalCard renders the hire blueprint (name, purpose, soul preview, skill packs, first task) with Approve/Reject; its status is read from the LIVE work.approval record (pending/provisioning/hired/rejected), not the transient tool result; the buttons emit a resolve_approval action whose registered handler calls work.approval.resolve oRPC out-of-band (the agent never pauses). Cards dedupe by approvalId so N duplicate proposes render ONE card."
+        },
+        {
+          "id": "L24-003",
+          "title": "P0-B: provision-on-approve, decoupled from the heartbeat loop",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The root-cause fix for the dead magic moment. Today hire provisioning runs only inside #reconcileHires() at the START of the next goal-pursuit heartbeat — but the loop is OFF by default, so an APPROVED hire is NEVER provisioned. Make work.approval.resolve(approve) for a hire approval INLINE-trigger the same hireAgent(approvalId) reconcile immediately, independent of the loop. Idempotent + replay-safe via the existing consumed_at guard. After approve, the employee appears in the roster within seconds whether or not the loop is enabled."
+        },
+        {
+          "id": "L24-004",
+          "title": "Looplia emits the HireApprovalCard via render_ui after hire_agent propose",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Closes the chat-native hire loop: when the user asks Looplia to hire, Looplia calls hire_agent(propose) to create ONE pending approval, then calls render_ui with a HireApprovalCard spec bound to that approvalId — so the approve happens INLINE in the chat, not on a separate surface. One propose = one card (no duplicate-hire spam)."
+        },
+        {
+          "id": "L24-005",
+          "title": "Consolidated PendingApprovalsList (one catch-all home; delete the duplicate)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Loop-originated approvals (budget hard-stop, autonomous hire) have NO chat turn to attach to, so they need a durable home. Replace the TWO duplicate approval surfaces (Mission ApprovalsView + the buried Work-board ApprovalStrip) with ONE PendingApprovalsList that reuses the HireApprovalCard and the same resolve+provision path, plus a lightweight 'Needs you (N)' indicator in the company shell reachable from the chat spine."
+        },
+        {
+          "id": "L24-006",
+          "title": "P0-C: manual create-agent failures must surface (no silent close)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Dogfood showed the manual 'Create with defaults' dialog closing silently with no agent and NO error — success and failure are indistinguishable. Make agent.create failures keep the dialog OPEN and show a clear error, and reproduce the actual server error so the underlying create failure (the other half of the hire P0) is fixed."
+        },
+        {
+          "id": "L24-007",
+          "title": "Layer 24 gate — inline hire in chat, end to end",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Proves the Wave-1 hire vertical: a user can hire an employee entirely inside Talk-to-Looplia (propose -> inline HireApprovalCard -> Approve -> provisioned), with the loop OFF, plus the consolidated list + P0 fixes. Guards the dogfood-confirmed dead-end from regressing."
+        }
+      ]
+    },
+    {
+      "layer": 25,
+      "counts": {
+        "completed": 10
+      },
+      "total": 10,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L25-001",
+          "title": "Hire reflects the requested role (derive blueprint from the conversation, not a generic Assistant)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Layer 24's inline-hire magic moment WORKS but is carried entirely by server-side backstops: the Looplia model cannot reliably populate hire_agent's nested `blueprint` arg (4 dogfoods showed it looping `{mode:'propose'}` with no role), so 'hire a research assistant' provisions a generically-named 'Assistant'. Derive the blueprint (name/slug/purpose) server-side from the triggering user request / recent conversation so the hired employee matches the role asked for. Moves the moment from 'works' to 'feels right' and stops every hire collapsing onto the single 'assistant' slug."
+        },
+        {
+          "id": "L25-002",
+          "title": "render_ui card reload-rehydration (persist + restore tool-call parts so inline cards survive a full reload)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Closes the deferred L24-002 durability AC. Inline generative cards (HireApprovalCard and any future render_ui card) currently DROP on a full page reload — they persist in-session and re-render on re-ask, but a hard reload loses them. Root cause (found in L24-004): the OUTBOUND turn persist (packages/do-agent/src/lib session-history.ts assembleAssistantMessages) stores assistant TEXT ONLY and drops tool-call/result parts, so a render_ui spec only reaches assistant_messages via a later inbound echo that the out-of-band hire flow never produces. Persist the tool-call/result parts on the outbound turn and rehydrate them on load."
+        },
+        {
+          "id": "FIX-TESTS-001",
+          "title": "Refresh stale unit-test expectations (COO tool count + advisory-blueprint mismatch)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Three unit tests assert OLD behavior and are red on main, eroding the suite's signal (a green run no longer means 'nothing broke'). They are stale expectations, not product bugs: the code is correct, the assertions lag prior intentional changes. Refresh them so the suite is trustworthy."
+        },
+        {
+          "id": "FIX-HIRE-005",
+          "title": "Thread the conversation context to the LIVE COO hire path so role-derivation actually fires (L25-001 dogfood NO-GO)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "L25-001 merged (#238) with passing contract tests but the 2026-06-29 prod dogfood found it INEFFECTIVE live: 'hire a research assistant' AND 'hire a data analyst' both still provision a generic 'Assistant'. The model omits hire_agent's blueprint arg (its own words: 'called with only mode and no blueprint') — exactly the case L25-001 was meant to cover by server-deriving the role from the triggering message — yet draftBlueprint falls back to generic, so the conversation context is NOT reaching it on the live COO/company-agent hire path. The contract tests pass only because they call proposeHire WITH context directly (the same scripted-green/model-path-broken trap as L13/L24). Make the role derive on the REAL path so every hire reflects the requested role."
+        },
+        {
+          "id": "FIX-TESTS-002",
+          "title": "Refresh / quarantine 3 pre-existing unrelated do-agent test reds (trustworthy-signal hygiene)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "3 pre-existing do-agent reds (skill-loader sync x2, migrateEmailStore SQL spy) are unrelated to any L25 story but have shadowed every recent gate as 'known-red baseline' — forcing every build to judge by stash-diff instead of absolute green. They have nothing to do with the hire vertical; they're stale/environment-coupled assertions. Refresh or explicitly quarantine them (with a documented reason) so `cd packages/do-agent && bun test` is a trustworthy absolute-green signal again. Strengthen, don't weaken — if a red reflects a real defect, fix it; if it's an outdated assertion or a flaky spy, repair the assertion or mark it skip with a tracked reason."
+        },
+        {
+          "id": "FIX-TESTS-003",
+          "title": "Break the @looplia/agent-runtime barrel circular-export cycle (2 do-agent test files error at module-load)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Surfaced by FIX-TESTS-002: 2 do-agent test files (index.test.ts, tools/run-long-shell.integration.test.ts) ERROR at module-load on a circular-export in @looplia/agent-runtime's barrel — ./spawn -> ./fiber -> @cloudflare/think (the workerd-only SDK) throws mid-eval under bun's loader, leaving ./spawn partially initialized so a named export (DEFAULT_AWAITER_TIMEOUT_MS) that DOES exist appears missing. It cascades into @looplia/db (sessionTicket) when chased, can't be it.skip'd (top-level import throws), and was red on baseline (not a regression). These 2 errors are the entire remaining do-agent known-red baseline after FIX-TESTS-002. Low priority (test-infra only, no shipped-behavior impact known) but tracked so the do-agent suite can reach true absolute-green."
+        },
+        {
+          "id": "FIX-EMAIL-READ",
+          "title": "read_mail must return the decoded body text (agents are blind to inbound email — dogfood NO-GO)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "2026-06-30 autonomous-campaign dogfood: the hired employee could NOT read any inbound reply. read_mail (tools/mail.ts -> MailAgentRef.getMessage -> handleGetMessage) returns only an email_message row + a signed R2 URL, never the body. The agent cannot dereference that URL from inside the DO (run_edge -> edge_unavailable because LOADER is unbound/closed-beta; no daemon; cf_facet can't fetch), so it literally cannot read the counterparty's message. Its own reasoning trace (trajectory run heartbeat-3bf7ab61): 'I can't read email bodies directly through the API.' This silently breaks ALL inbound comprehension — the agent ignored the CEO's explicit (Chinese-language) request because it never could read it."
+        },
+        {
+          "id": "FIX-EMAIL-INBOUND-WAKE",
+          "title": "Wake the owning employee on an inbound reply + project it into the supervisor ledger (nothing wakes the agent; COO sees '0 replies')",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Same dogfood: inbound mail is PASSIVE — LoopliaCompany.onEmail -> facet.ingestInboundEmail -> #dispatchInbound -> handleInboundEmail stores the row + fans out email.received webhooks, but creates NO task and schedules NO wake. Nothing wakes the recipient employee on a reply, and the COO (which reads the supervisor work-ledger — a DIFFERENT SQLite store from the facet's email_message rows) never sees it -> the COO's status said '0 replies' while a reply sat unread (state desync). Replies must promptly wake the owner AND be visible to the COO."
+        },
+        {
+          "id": "FIX-EMAIL-PRECEDENCE",
+          "title": "Obey explicit counterparty instructions (language/format/stop) + gate outbound cadence (6 unsolicited follow-ups; ignored a request)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Same dogfood: (a) the agent ignored the CEO's explicit Chinese-language request — partly because it couldn't read it (FIX-EMAIL-READ), but the skill also never tells it that an explicit counterparty instruction overrides the goal's default style; (b) it sent 6 teasers before any reply because the heartbeat re-runs the same 'email the user' goal each tick with no awaiting-reply gate. Make it read-then-obey and stop hammering."
+        },
+        {
+          "id": "FIX-TRAJ-CHAT-REASONING",
+          "title": "Capture reasoning on the live /agui chat path so 'Talk to Looplia' turns are observable in the trajectory (Part A)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "While diagnosing the dogfood we confirmed the trajectory log DOES capture per-step reasoning on autonomous/heartbeat runs (that's how we read the employee's 'I can't read email bodies' trace) — but the interactive /agui chat path does NOT. #runStreamSse -> runStreamOpenRouter (run-stream.ts ~681) omits the reasoning providerOptions that runModelStep (~1054) passes and has no reasoning-delta handling, so interactive chat turns persist no reasoning. This is the L21 'dogfood pending: live reasoning' gap: when a human talks to Looplia, we can't see how it reasoned."
+        }
+      ]
+    },
+    {
+      "layer": 26,
+      "counts": {
+        "completed": 11
+      },
+      "total": 11,
+      "gate_status": "scripted_passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L26-MEM-001",
+          "title": "Execution-loop memory write-back parity — the heartbeat/task loop must route back into durable memory, not only read it",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "2026-07-01 dogfood root cause: an operating employee READS memory every heartbeat/task turn but NEVER writes back. Both write-back mechanisms are wired to the /agui chat path only — the scheduled consolidator reads assistant_messages (heartbeat turns live in agent_run_step) and the L8 self-review fires on onTurnComplete which hostAgentRun never sets. So an autonomous employee's learned work-items + counterparty preferences are lost. This is the keystone: without it, a continuously-operating agent cannot self-record what it did or learned."
+        },
+        {
+          "id": "L26-MEM-002",
+          "title": "Make consolidation a company-protocol step + relax manage_memory friction for task-derived preferences",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Even with the write-back seam (L26-MEM-001), the contract + tool actively discourage recording: the 8-step company-protocol heartbeat contract has NO memory step (durable progress = comments/files/emails/results only), and manage_memory's own description says 'DO NOT SAVE: task progress / completed-work logs' while resolvePerson rejects a counterparty given by email/display-name. So the model is told not to, and can't easily address an external counterparty."
+        },
+        {
+          "id": "L26-MEM-003",
+          "title": "Extend Hermes-style auto-skill-from-experience to the execution loop (learn skills from what employees DO)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The L8 self-review already authors /skills/<name>/SKILL.md at runtime from experience — but ONLY on the /agui chat path. A hard-working employee that repeats a workflow (e.g. a reader-outreach sequence) never grows a skill, so the company never compounds operational know-how from execution. The CEO's thesis: executed tasks should produce Hermes-style auto-generated skills."
+        },
+        {
+          "id": "L26-MEM-004",
+          "title": "Relational memory storage model — homes + task-relevant retrieval for many typed relationships (owner, peers, external counterparties)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Today's memory is single-owner-centric: /memory/people/<personId>.md is keyed by a STABLE id, resolvePerson defaults to the owner + rejects an email/display-name counterparty, and assemble.ts injects ONLY the primary person. So an operating agent that relates to the OWNER/CEO, SIBLING AGENTS, and MANY external customers has no home for most relationships and cannot recall the RIGHT one per task. This is the CEO's storage-model research (docs/research-note/19)."
+        },
+        {
+          "id": "L26-EXEC-001",
+          "title": "Goal-ownership recursion — an employee owns a standing goal (owned-goal marker + generalize routeHeartbeatWake + parametrize the goal-pursuit assembler)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Today only the COO owns a standing goal (the north-star anchor) and pursues it via runGoalPursuitTurn; employees are reactive one-shot-task workers. The goal-pursuit machinery is 'generic except one hard-coded comparison' (routeHeartbeatWake: taskId === NORTH_STAR_ANCHOR_TASK_ID). Generalizing it lets an EMPLOYEE own + autonomously pursue its own standing goal with the same reconciliation/dedup/self-sync the COO gets — the keystone of the execution track."
+        },
+        {
+          "id": "L26-EXEC-002",
+          "title": "Per-owned-goal cadence policy (active / awaiting_reply / paused) on tasks",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The scheduler (EXEC-003) needs to know WHICH owned goals to tick and how often, and awaiting_reply is the general form of the FIX-EMAIL-PRECEDENCE 'stop hammering' gate. A cadence policy on the owned-goal task is the enumeration key."
+        },
+        {
+          "id": "L26-EXEC-003",
+          "title": "Single-clock scheduler fan-out to goal-owners + #needsSupervision (COO throttle) — wire the dead wakeForSchedule seam",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The efficiency + autonomy win: today every cron tick wakes the COO for a full goal-pursuit turn (COO turn + employee turn per unit of progress); the COO acts as a per-tick router that needs no model. Fanning out schedule-wakes to goal-owning employees directly drops steady-state cost to ~1 employee turn per active goal per cadence, with the COO amortized to occasional planning."
+        },
+        {
+          "id": "L26-EXEC-004",
+          "title": "Unify heartbeat + event into one trigger taxonomy (buildTurnTrigger) + generalize the email_received trigger",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Today buildHeartbeatTrigger vs buildNorthStarTrigger fork the opener, and the inbound-email wake (FIX-EMAIL-INBOUND-WAKE) reuses the 'mention' trigger as a stand-in because RunTrigger has no email kind. Unifying makes every wake — schedule OR event — one RunTrigger kind on one pipeline (persona + memory + goal + trigger payload → response), so events get the same trajectory/reasoning capture and a first-class email_received kind."
+        },
+        {
+          "id": "L26-EXEC-005",
+          "title": "Employee scoped delegation under its owned goal (decompose without gaining hire/mission verbs)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "To autonomously complete an independent goal, an employee must decompose it into subtasks under its own goal. It already has create_subtask, but the goal-pursuit bias + create_task/hire/mission are company-agent-only. Grant an employee scoped decomposition under ITS owned goal while KEEPING hire_agent / set_company_mission / cross-agent delegation COO-only — the trust hierarchy."
+        },
+        {
+          "id": "L26-EXEC-006",
+          "title": "Owned-goal create surface — assign a standing goal to an employee (unblock goal-ownership end-to-end)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "L26's HEADLINE promise — an employee autonomously owns + is woken directly on a standing goal (EXEC-001/002/003) — is UNREACHABLE through the running product: `ownedGoal:true` is a store primitive set ONLY by test fixtures (direct supervisor.createTask). No model-facing tool (create_task/create_subtask omit it), no oRPC (work/task/create omits it), no assignStandingGoal procedure, no production caller (hire creates a one-shot task, not a standing goal). So the scheduler fan-out + #needsSupervision throttle are proven Tier-1-only; a user/COO can never create an owned goal. This story is the missing FRONT DOOR that flips the L26 gate's goal-ownership half from scripted-only to product-reachable + dogfoodable. (e2e_review discovery 2026-07-02.)"
+        },
+        {
+          "id": "FIX-SKILL-REVIEW-001",
+          "title": "Self-review skill-authoring is structurally dead in prod — REVIEW_ALLOWED_TOOLS vs the L15-005 skill-write guard",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The Hermes skill-from-experience loop (L8, extended to execution turns by L26-MEM-003) cannot author or patch a skill in production BY ANY ROUTE: the review tool gate (REVIEW_ALLOWED_TOOLS, review-run.ts:166) allows write/edit 'for skill management', but guardSkillWrites (L15-005) rejects every generic write to /skills/** at the workspace seam (index.ts:3819), and the one validated skill-write path — manage_skill — is NOT in the allowlist, so reviewBeforeToolCall denies it. The L26-MEM-003 gate test passed because its dispatchTool stub bypassed the guard (execution-skill-learning.test.ts:152) — production dispatch (agentRunDispatchTool -> registeredTools, index.ts:3546) is guarded. Scripted-green/live-broken recurrence #4. Discovered by the 2026-07-07 design-review code walk (docs/research-note/22, D0)."
+        }
+      ]
+    },
+    {
+      "layer": 27,
+      "counts": {
+        "completed": 6
+      },
+      "total": 6,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L27-001",
+          "title": "Owned-goal cadence lifecycle — wire the dead policy writes (park / resume / per-goal cadenceSeconds)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The EXEC-002 cadence machinery is read by the scheduler but NOTHING writes it: setCadencePolicy has zero callers (work-store.ts:753), every owned goal is born active and ticks forever, awaiting_reply/paused/done are unreachable, and assignStandingGoal's cadenceSeconds is Zod-validated then ignored (company-autopilot.ts:170). A biweekly-newsletter goal burns a wake every loop tick. This story makes the cadence model true: goals park themselves, events resume them, and per-goal cadence is honored — the real per-active-goal-per-cadence cost model research-note/18 §3.1 promised. (research-note/21 G2)"
+        },
+        {
+          "id": "L27-002",
+          "title": "Goal completion lifecycle — satisfied (employee) -> verified (COO) -> retired",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Owned goals are immortal: no success-criteria evaluation, no goal-satisfied proposal, no COO verification, no retirement — an autonomous company whose goals never finish is a treadmill, not an organization. This story gives a standing goal a terminal, auditable state using the EXISTING task-status machine (no new states). (research-note/21 G3)"
+        },
+        {
+          "id": "L27-003",
+          "title": "COO standing-goal ignition — assign_standing_goal COO tool (approval-gated, graduated autonomy)",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The L26 recursion has no autonomous write-half: assignStandingGoal is human-oRPC-only (company-autopilot.ts:243) and the COO has NO tool to mint a standing goal — the chain COO-decomposes-north-star-into-employee-owned-goals (the whole point of research-note/20's role table) cannot execute without a human calling an RPC per goal. This is THE story that makes the company self-organizing. (research-note/21 G1)"
+        },
+        {
+          "id": "L27-004",
+          "title": "Hire-for-goal — hire blueprint carries an optional standing goal",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "hireAgent provisions the agent then creates a ONE-SHOT firstTask (company.ts:2033) — but in this company model a hire IS a mission assignment. Carrying an optional standingGoal in the blueprint means the hire approval the CEO reviews shows the mission the employee will own, and provisioning lands the employee already goal-owning. (research-note/21 G6)"
+        },
+        {
+          "id": "L27-005",
+          "title": "Structured escalation — employee escalate verb routed into supervision",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "An employee that hits a wall can only park a task blocked and hope the passive blocked_task scan eventually wakes the COO — there is no way to say WHY or WHAT it needs (help, a re-plan, a missing capability/hire). Structured escalation makes employee autonomy safe: walls surface immediately with intent, instead of as silent stalls. (research-note/21 G4)"
+        },
+        {
+          "id": "L27-006",
+          "title": "Strategy surface — strategic decision log, cadenced CEO briefing, approval-gated strategy changes",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The COO plans silently: strategy derived each supervision turn evaporates (appendCompanyPlanDecision has ZERO callers — owner Decision B was right for L19, wrong for an autonomous company whose strategy must be auditable), there is no CEO briefing, and no channel for the COO to PROPOSE a mission change. This story is what makes Looplia a COO that ASSISTS the CEO — reports, advises, and records — rather than a scheduler. (research-note/21 G5)"
+        }
+      ]
+    },
+    {
+      "layer": 28,
+      "counts": {
+        "completed": 5
+      },
+      "total": 5,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L28-001",
+          "title": "Goal-scoped working memory — /memory/goals/<goalId>.md, the memory half of standing-goal continuity",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "A standing goal is pursued across many wakes but has NO goal-scoped durable working state — progress lives only in ledger comments and whatever consolidation routes to /memory/notes.md, so every schedule wake re-derives the approach from scratch. The research-note/19 replay test only half-passes today: counterparty prefs persist (MEM-004) but the WORK state (episode 2 of 3 sent; next: draft ep-3 protagonist arc) does not. (research-note/22 D1)"
+        },
+        {
+          "id": "L28-002",
+          "title": "Memory budget visibility + consolidation guarantees — stop failing silently at the 1500-token cap",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "As a goal-owning employee accumulates notes/people/counterparties/org/mounts, lower-priority sources silently DROP from the turn with no signal to the agent or user; an over-cap file gets a will-be-consolidated promise that nothing enforces (it can wedge at cap); a persistently-garbled distill retries the same window forever (fail-open); and the shared 50-report _curator/runs feed lets a chatty phase evict another phase's audit trail. Four small reliability holes in an otherwise-correct substrate. (research-note/22 D3)"
+        },
+        {
+          "id": "L28-003",
+          "title": "Relationship lifecycle at scale — hot/warm/cold index, cold archival, unresolved-counterparty home",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "MEM-004 gave counterparties a durable home but no lifecycle: a busy outreach employee accrues hundreds of /memory/people/ext files with no hot/warm/cold distinction, no archival, and a party known only by display name has NO home at all — its facts fall into notes.md where counterparty keying never recalls them. The scaling tier research-note/19 §B.3 explicitly deferred. (research-note/22 D2)"
+        },
+        {
+          "id": "L28-004",
+          "title": "Company skill library — promote proven skills to the wiki tier; seed hires from what the org learned",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Each agent's /skills is an island (deliberate L7-005 identity choice) — what Reader-Outreach learns about email cadence dies with it and every new hire starts from the generic pack. Circulating proven skills through the EXISTING shared tier (/company/wiki, company-agent-writable, all-readable) makes organizational learning compound — the Hermes loop at the org level, not just the agent level. (research-note/22 D4)"
+        },
+        {
+          "id": "L28-005",
+          "title": "Memory as a company asset — deprovision export (OKF bundle) + two-phase teardown",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "deleteAgent -> tearDownWorkspace destroys the agent's Workspace outright (and silently ORPHANS R2 objects if it fails mid-way — the supervisor deletes the facet's SQLite but deleteSubAgent never frees R2). An agent's accumulated memory/skills — a company asset the CEO paid to build — has no exit path and no audit trail. (research-note/22 D6... D5)"
+        }
+      ]
+    },
+    {
+      "layer": 29,
+      "counts": {
+        "completed": 4
+      },
+      "total": 4,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L29-001",
+          "title": "Operating-state projection v2 — goal-portfolio picture refreshed by employee turns",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The 600-char /org/company-state.md projection is COO-shaped and goes STALE on employee work: syncCompanyState runs only at the end of north-star-mode turns (index.ts:4422 — employee owned_goal turns explicitly skip it) plus mission/brief writes, and its count-based summary predates owned goals. Post-L26/L27 most company progress happens on exactly the turns that never refresh the shared picture — every agent then coordinates against a stale, goal-blind snapshot. (research-note/23 S1)"
+        },
+        {
+          "id": "L29-002",
+          "title": "Scoped board visibility — read-only list_company_work for every agent",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Employees are context-blind by over-restriction: list_tasks is COO-only, so an employee's entire company awareness is the projection line — it cannot see even a scoped view of adjacent work. Safe when employees were one-shot workers; goal-owning employees coordinating around shared counterparties need a careful notch more. Visibility is not authority: the trust hierarchy (create/assign/hire) is untouched. (research-note/23 S3)"
+        },
+        {
+          "id": "L29-003",
+          "title": "Knowledge lifecycle — briefing archive, goal dossiers, wiki curator + sources digest",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "The wiki holds a brief and a README — the knowledge tier has no life: nothing writes operating knowledge into it, nothing curates it, and connector mounts contribute nothing ambient. This story turns /company/wiki into the company's operating library, written by the loops L27 creates. (research-note/23 S2+S5; the storage/artifact half of L27-006's behavior)"
+        },
+        {
+          "id": "L29-004",
+          "title": "Freshness for every agent + the shared-context stability contract",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "Staleness data exists but only the COO can see it (inspect_context_freshness; changedSinceConfirmation) — an employee citing a stale brief has no way to know. And the shared-context invariants that keep the whole system stable (bounded projection, OKF conformance, projection never dropped by budget, dead seams not built upon) are conventions, not tests — one regression away from silent rot. (research-note/23 S4)"
+        }
+      ]
+    },
+    {
+      "layer": 30,
+      "counts": {
+        "completed": 4
+      },
+      "total": 4,
+      "gate_status": null,
+      "is_current": false,
+      "stories": [
+        {
+          "id": "FIX-COO-NO-MISSION",
+          "title": "Idle-spin cost guard — the loop stops (or deep-idles) when there is no progress to make",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "PURPOSE: stop paying for idle spin. 2026-07-08 prod dogfood proved the loop does NOT self-stop when there is nothing to do — it burned the account to its $20 hard-stop on no-progress COO turns. Root cause is in code, not just empty state: needsSupervision (supervision.ts:587) returns true — waking a paid COO model turn — on any STICKY item (a blocked/unassigned task, an in_review goal, a pending approval) EVERY tick until it is resolved, so one leftover blocked task (the dogfood's 'blocked 1') re-woke the COO every single tick forever; plus an UNCONDITIONAL periodic replan_interval wake (every 12x interval) fires even with no mission and no goals. The only things that ever STOP it are the coarse budget hard-stop and MAX_TICKS/day — there is no idle detector. And 'productive tick' (company.ts:2153) means 'minted a run', not 'made progress', so a COO that wakes, looks around, and does nothing still counts as productive and still costs money. (dogfood finding 1)"
+        },
+        {
+          "id": "REF-COO-CADENCE-EDIT",
+          "title": "Reach L27-001 setOwnedGoalCadence through the COO — 'change an employee's cadence' must modify, not re-hire",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "2026-07-08 prod dogfood: asking Looplia to change an existing employee's standing-goal cadence produced a NEW hire proposal (deduped harmlessly, but the intent was lost) instead of calling L27-001's shipped setOwnedGoalCadence on the existing owned-goal anchor. The park/resume/per-goal-cadence machinery exists but is unreachable through the natural COO chat instruction. (dogfood finding 2)"
+        },
+        {
+          "id": "ENABLE-DOGFOOD-CADENCE",
+          "title": "Dogfood cadence accelerator — make long-cadence behaviors (briefing, dossier, daily curators) verifiable in one session",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "2026-07-08 prod dogfood verified the core vertical live but could NOT observe the long-cadence background behaviors — L27-006 CEO briefing (replan_interval ~hourly), L29-003 goal dossiers + wiki curator, L28-003 relationship archival, L28-004 skill promotion (all daily-gated). Without a way to fast-forward these, ~5 shipped stories can never be dogfood-verified, so their layer outcome contracts stay open indefinitely. (dogfood process finding)"
+        },
+        {
+          "id": "REF-TURN-DATE",
+          "title": "Inject the current date into the agent turn context — agents hallucinate the year",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": "2026-07-08 prod dogfood: the Research Writer's autonomous email subject read 'Daily Autonomous AI Agent Research Summary - 2025-07-07' — a year wrong (system date is 2026). Agents fabricate the date because the turn context doesn't reliably carry it. Cosmetic here, but a dated-artifact company (briefings, dossiers, summaries) that misdates its own output erodes CEO trust. (dogfood finding 3)"
+        }
+      ]
+    },
+    {
+      "layer": 31,
+      "counts": {
+        "completed": 19,
+        "deferred": 2
+      },
+      "total": 21,
+      "gate_status": "passed",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L31-001",
+          "title": "Versioned employee capability contracts and archetype registry",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-002",
+          "title": "Immutable baseline and learned-overlay skill composition",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-012",
+          "title": "Professional execution requirement descriptors and deterministic qualification driver",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-013",
+          "title": "Newsroom formation profile and company-context bootstrap",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-007",
+          "title": "Typed newsroom artifact contracts and role write boundaries",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-008",
+          "title": "Shared newsroom-core skill pack",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-009",
+          "title": "Paper Researcher role pack and deterministic qualification fixtures",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-010",
+          "title": "Startup Writer role pack and deterministic qualification fixtures",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-003",
+          "title": "EmployeeBlueprintV2, exact hire approval and provisioning lock receipt",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-004",
+          "title": "Qualification state machine and evidence-backed capability profile",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-011",
+          "title": "Professional hire approval and readiness UI",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-014",
+          "title": "Readiness invalidation and scheduler/assignment wake enforcement",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-005",
+          "title": "COO capability-aware assignment routing",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L31-006",
+          "title": "Hire-to-ready technology newsroom integration gate",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L31-DOGFOOD-SECRETS-001",
+          "title": "Harden the production dogfood credential boundary and make the Layer-31 full-reset gate runnable",
+          "status": "deferred",
+          "stage": 1,
+          "exception": "deferred",
+          "why": null
+        },
+        {
+          "id": "FIX-L31-DOGFOOD-SECRETS-002",
+          "title": "Recovery V2: structurally confine dogfood secrets, separate reset plans from executor authority, and restore workspace configuration",
+          "status": "deferred",
+          "stage": 1,
+          "exception": "deferred",
+          "why": null
+        },
+        {
+          "id": "FIX-L31-SECRET-BOUNDARY-003",
+          "title": "Finite fail-closed secret boundary for the dogfood drivers, then run the Layer-31 full-reset production gate",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L31-FRESH-COMPANY-INIT-004",
+          "title": "Initialize the Company work ledger before a fresh account's first protected RPC",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L31-COMPLETED-REPLAY-MUTATION-009",
+          "title": "Reject caller blueprint replacement before replaying a completed professional hire receipt",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L31-AGUI-TOOL-RESULT-TIMEOUT-010",
+          "title": "Return professional create_task results before the AGUI deadline and recover orphaned tool calls",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L31-NEWSROOM-V2-LINEAGE-011",
+          "title": "Reconcile a higher newsroom profile through existing professional lineage",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 32,
+      "counts": {
+        "completed": 11,
+        "failed": 2
+      },
+      "total": 13,
+      "gate_status": "scripted_passed",
+      "is_current": true,
+      "stories": [
+        {
+          "id": "L32-001",
+          "title": "ExecutionProfile resolver and ExecutionJob state machine",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-002",
+          "title": "Cloudflare Sandbox adapter and pinned paper-analysis Python image",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "FIX-L32-SUPERVISOR-START-001",
+          "title": "Stabilize fresh-identity Sandbox supervisor start",
+          "status": "failed",
+          "stage": 3,
+          "exception": "failed",
+          "why": null
+        },
+        {
+          "id": "FIX-L32-CANARY-502-001",
+          "title": "Diagnose non-contract Sandbox canary 502 envelope",
+          "status": "failed",
+          "stage": 3,
+          "exception": "failed",
+          "why": null
+        },
+        {
+          "id": "FIX-L32-CANARY-502-002",
+          "title": "Repair signed Sandbox canary transport boundary",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-003",
+          "title": "Scholarly Codemode driver and provider surface",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-010",
+          "title": "Governed E0/Workspace driver and professional tool rollout",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-004",
+          "title": "Immutable input/artifact manifests, verification, replay and reap",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-009",
+          "title": "Autonomous newsroom signal discovery and pitch prioritization",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-006",
+          "title": "Paper Researcher production of ClaimLedger and ResearchDossier",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-007",
+          "title": "Startup Writer claim-linked article and publication package production",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-008",
+          "title": "Independent researcher fact-check of exact ArticleDraft version",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L32-005",
+          "title": "Professional newsroom execution integration gate",
+          "status": "completed",
+          "stage": 5,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 33,
+      "counts": {
+        "ready": 1,
+        "pending": 8
+      },
+      "total": 9,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L33-001",
+          "title": "Company policy ∩ Agent Operating Contract ∩ grant decision lattice",
+          "status": "ready",
+          "stage": 2,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-002",
+          "title": "Common ActionIntent effect-gateway core and Decision Receipts",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-009",
+          "title": "Explicit effect-gateway adapters for every physical entrypoint",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-003",
+          "title": "Typed command-chain artifacts and non-amplifying delegation",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-004",
+          "title": "Newsroom operating policy and exact-version publication approval",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-008",
+          "title": "Authorized source outreach, reply ingestion and evidence integration",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-006",
+          "title": "Thin Looplia Native CMS with exact publish and reconciliation",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-005",
+          "title": "Authority parity, revocation and command-chain adversarial gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L33-007",
+          "title": "First governed technology-news publication gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 34,
+      "counts": {
+        "pending": 7
+      },
+      "total": 7,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L34-001",
+          "title": "ExperienceRecord and typed feedback attribution",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-002",
+          "title": "Immutable baselines, learned overlays and exact skill locks",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-006",
+          "title": "COO workforce evidence diagnosis and bounded intervention set",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-003",
+          "title": "Replay A/B, counterexample evaluation and canary promotion lifecycle",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-004",
+          "title": "Capability growth evidence and requalification",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-007",
+          "title": "COO team capability portfolio and composition proposals",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L34-005",
+          "title": "Newsroom correction-to-learning and workforce-adaptation gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 35,
+      "counts": {
+        "pending": 6
+      },
+      "total": 6,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L35-001",
+          "title": "CompanyEvent v1 with transactional outbox/inbox dedup",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L35-006",
+          "title": "Outbox pump, Cloudflare Queue wiring and delivery acknowledgements",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L35-002",
+          "title": "Queue consumer, DLQ quarantine and repair/replay",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L35-003",
+          "title": "Cloudflare Workflows bridge with event/approval waits and effect reconciliation",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L35-004",
+          "title": "Durable newsroom commission-to-approval workflow",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L35-005",
+          "title": "Durable newsroom failure-recovery gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 36,
+      "counts": {
+        "pending": 4
+      },
+      "total": 4,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L36-001",
+          "title": "Deliberation session, participant and scoped evidence model",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L36-002",
+          "title": "Independent-first positions, one cross-exam and claim verification",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L36-003",
+          "title": "Dissent-preserving COO synthesis and authority routing",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L36-004",
+          "title": "Bounded newsroom editorial-conference gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 37,
+      "counts": {
+        "pending": 6
+      },
+      "total": 6,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L37-001",
+          "title": "Privacy-safe end-to-end trace and version correlation contract",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L37-002",
+          "title": "Evaluation Registry for autonomous behavior versions",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L37-003",
+          "title": "Company/newsroom SLI, SLO and health projection",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L37-004",
+          "title": "Assured rollout, risk-aware fallback and rollback",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L37-006",
+          "title": "Deterministic incident containment, evidence hold and authorized recovery",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L37-005",
+          "title": "Newsroom regression containment and forensics gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 38,
+      "counts": {
+        "pending": 5
+      },
+      "total": 5,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L38-001",
+          "title": "DataDescriptor, classification, purpose and lineage foundation",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L38-002",
+          "title": "Correction, supersede, quarantine, retention and legal hold",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L38-003",
+          "title": "Company residency profile and placement enforcement",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L38-004",
+          "title": "RecoveryManifest, isolated restore and effect reconciliation",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L38-005",
+          "title": "Newsroom retraction propagation and continuity gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 39,
+      "counts": {
+        "pending": 6
+      },
+      "total": 6,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L39-001",
+          "title": "BusinessSystemAdapter contract and conformance suite",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L39-002",
+          "title": "Mature the thin CMS port into update/hold/withdraw/correction conformance",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L39-003",
+          "title": "Newsletter as a separately authorized staged effect",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L39-006",
+          "title": "Per-channel social distribution canary",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L39-004",
+          "title": "Correction intake and verified editorial outcome ledger",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        },
+        {
+          "id": "L39-005",
+          "title": "Full technology-newsroom production closure gate",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 40,
+      "counts": {
+        "pending": 1
+      },
+      "total": 1,
+      "gate_status": null,
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L40-001",
+          "title": "Separate develop and main deployment environments",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    },
+    {
+      "layer": 41,
+      "counts": {
+        "pending": 1
+      },
+      "total": 1,
+      "gate_status": "not_started",
+      "is_current": false,
+      "stories": [
+        {
+          "id": "L41-001",
+          "title": "Cloudflare-only autonomous newsroom dynamic exploration, source reading and information integration",
+          "status": "pending",
+          "stage": 1,
+          "exception": null,
+          "why": null
+        }
+      ]
+    }
+  ],
+  "changelog_recent": [
+    {
+      "id": "2026-07-22-dispatch-203",
+      "date": "2026-07-22",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-010 (Governed E0/Workspace driver and professional tool rollout) as Layer-32 Wave-2 at epoch 85. It is the highest-scoring ready story (95), depends only on completed L32-001, and unlocks the verification convergence story L32-004. The full design preserves the compact execution facade, binds qualified professional turns server-side, uses exact descriptor-bound WorkEffectPermit admission, and forbids arbitrary model code, shell, runtime selectors, privilege escalation, artifact promotion and direct success.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-reflection-204",
+      "date": "2026-07-23",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-010 completed in PR #341 at merge SHA 476e5400. The implementation adds a closed deterministic E0/Workspace driver, descriptor-bound WorkEffectPermit admission, a concrete authenticated production registration reachable from LoopliaAgent stream and agent_run turns, fail-closed stale/assessment-error routing, durable same-D1 replay with one Workspace mutation, and a stable host-owned per-run selection token. Independent evaluation required four rounds after a standard-to-deep escalation: Round 1 found unreachable production registration, Round 2 found initial stale fallback plus missing durable replay and stale manifest, Round 3 found token identity and a lint race, and fresh-generator Round 4 passed with zero blocking/important findings. Final evidence: 190 story-scoped tests (1,488 expectations), evaluator subset 36 pass, typecheck/oxlint/oxfmt/frozen install, 214-callsite admission manifest, diff integrity and secret scan all pass. Tier-2/3 post-deploy journey evidence was refused because target-bound owner credentials/preflight were unavailable; no production deploy, reset, seed, browser journey or CI mutation was attempted. Layer 32 remains open because L32-003 and downstream stories are not yet completed.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-dispatch-205",
+      "date": "2026-07-23",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-004 (Immutable input/artifact manifests, verification, replay and reap) at epoch 87. It is the sole ready Layer-32 Wave-3 story after L32-002, L32-003 and L32-010 completed; it will bind licensed immutable manifests, deterministic verification, replay comparison and cleanup receipts without changing the frozen broker or provider surfaces.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-dispatch-206",
+      "date": "2026-07-23",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-003 (Scholarly Codemode driver and provider surface) as Layer-32 Wave-2 at epoch 86. It is the only remaining ready story (readiness 1.0, dispatch score 94) after L32-010 completed; it will route scholarly work through the shared E1 Codemode broker/driver with provider-neutral compact namespaces, typed ambiguity/freshness/license outcomes, and no daemon fallback.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-reflection-207",
+      "date": "2026-07-23",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-003 completed in PR #342 at merge SHA 36384e256de09adc676d64781826e73a3bff4d3a. The E1 Codemode scholarly surface adds exact broker-registered execution, compact provider-neutral papers/search/resolve/status and sources/fetchMetadata operations, Crossref/Crossmark status authority, Semantic Scholar discovery-only fallback, normalized/hash/freshness/license-bounded metadata, and durable tenant-scoped lifecycle reconciliation across stale markers, cancel/reap crashes and actor restarts. Independent deep evaluation required six rounds plus one explicitly human-approved post-cap round: R1–R5 progressively found and fixed authority, identity, privacy, timeout, durable replay, tenant isolation and cleanup-intent crash gaps; Round 6 passed with zero blocking/important/minor findings and all hard floors 4. Final evidence: focused 39/39, affected execution 249/249, cancel/reap crash harnesses, cross-tenant/stale-marker regressions, typecheck/oxlint/oxfmt, strict OpenSpec, 214-callsite admission manifest, diff integrity and gitleaks. No live credentials, network calls, local deploy, D1 reset/seed or production mutation occurred; post-deploy scholarly dogfood remains a Layer-32 gate concern. L32-004 is now ready because L32-002, L32-003 and L32-010 are complete.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-reflection-208",
+      "date": "2026-07-23",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-004 completed in PR #343 at merge SHA 1e2c92df. The execution plane now has immutable tenant-scoped input/artifact manifests, deterministic fail-closed verification with typed quarantine and receipts, exact replay comparison with explicit authorization, and driver-authoritative reap intent/evidence preservation. Independent deep evaluation required three bounded rounds: Round 1 found malformed/throwing evidence, replay scope/kind, reap identity and reference-confinement gaps; Round 2 closed the first regressions but found quarantine idempotency, unsafe refs and authorization classification gaps; Round 3 passed with zero blocking/important findings and all hard floors 4. Final evidence: 274/274 execution tests with 1,918 expectations, focused regression probes, typecheck/oxlint/oxfmt, strict OpenSpec, 214-callsite admission manifest, diff integrity and gitleaks. No live credentials, network calls, local deploy, D1 reset/seed or production mutation occurred; Layer-32 target-bound journey remains a downstream gate concern. L32-009 is now ready because its dependencies are complete.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-dispatch-209",
+      "date": "2026-07-23",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-009 (Autonomous newsroom signal discovery and pitch prioritization) at epoch 88. It is the highest-scoring ready Layer-32 story after L32-004 completed; the design will bind versioned company context, deterministic signal deduplication/prioritization, capability-gap parking and draft-only outreach without bypassing L33 authority.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-reflection-210",
+      "date": "2026-07-23",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-006 completed in PR #345 at merge SHA 4fa0f1ee, with product head 64cd35fd. The Paper Researcher now consumes exact ArticleAssignment tasks through the real heartbeat host bridge, derives and revalidates current newsroom context/readiness, routes scholarly work through the existing ProfessionalExecutionBroker and ScholarlyCodemodeExecutionDriver, and persists immutable tenant-scoped ClaimLedger/ResearchDossier artifacts with atomic response-loss replay. Independent deep evaluation required bounded fix rounds for task reachability, epistemic metadata, SQL/memory parity, current-context binding and driver-output integrity; final Round 5 and post-PASS Round 6 passed with zero blocking/important findings. Final evidence included 162 focused checks on the merged candidate and 176 checks for the persisted-output integrity delta, plus typecheck/oxlint/oxfmt, strict OpenSpec, admission 215, diff integrity and gitleaks. No live credentials, local deploy, Wrangler/OAuth or D1 mutation occurred.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-23-dispatch-211",
+      "date": "2026-07-23",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-007 (Startup Writer claim-linked article and publication package production) as Layer-32 Wave-6 at epoch 90. The strict design binds one qualified writer run to the exact L32-006 ClaimLedger/ResearchDossier and L31-010 editorial context, reuses the frozen ArticleDraft contract, and produces only a non-authorizing handoff package; L32-008 and L32-005 remain downstream.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-24-reflection-212",
+      "date": "2026-07-24",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-007 completed in PR #346 at merge SHA 898622cb from evaluated product head a4bb3e14. Startup Writer now runs from the routed article-assignment heartbeat path with strict capability/tenant/employee/context binding, emits immutable claim-linked ArticleDraft and source-derived non-authorizing publication package artifacts, and persists SQL-backed replay/tamper/conflict evidence. Independent evaluation passed with zero blocking/important findings for the shipped host seam: focused 100/100 with 641 expectations, worker writer 22/22, full newsroom 159/159 with one snapshot and 1,010 expectations; oxlint, oxfmt, diff check and strict OpenSpec passed. Typecheck retains only the pre-existing paper-analysis Sandbox missing dependency/brand errors. No deploy, OAuth, live credentials, local Wrangler or D1 mutation occurred.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-24-dispatch-213",
+      "date": "2026-07-24",
+      "kind": "dispatch",
+      "author": "aep-dispatch",
+      "summary": "Dispatched L32-008 (Independent researcher fact-check of exact ArticleDraft version) as Layer-32 Wave-7 at epoch 91. The strict design binds a fresh independent Paper Researcher run to the exact L32-007 draft/package, ClaimLedger, ResearchDossier and context, produces the frozen FactCheckReport, and persists only a non-authorizing verification receipt; L32-005 remains downstream.",
+      "since_baseline": false
+    },
+    {
+      "id": "2026-07-24-reflection-214",
+      "date": "2026-07-24",
+      "kind": "reflection",
+      "author": "aep-wrap",
+      "summary": "L32-005 completed in PR #348 at merge SHA cfd5431c, after independent deep evaluation PASS on exact feature head 6f26012f. The production composition now proves host-owned signal→pitch→research E1/E2→central immutable dossier handoff→claim-linked writer package→independent reviewer fact-check, including seeded overclaim/non-publish, immutable report/draft history, response-loss/cadence replay, stale requirements/readiness/route binding, revoked/package/egress/cross-tenant fail-closed parks, writer-shaped receipt protection, qualification-only authority/grant/roster/publication/effect stability and zero unauthorized effect counters. Focused 1/1, newsroom 97/97, routed/admission/index 14/14, protocol 19/19, admission 30/30, generated manifest 216 exact callsites; exact 32-path scope and strict OpenSpec/gitleaks/static gates passed. Exact product-merge Deploy run 30082737299 passed deployment, paper-analysis canary, evidence upload and supply-chain retention; a later docs-only wrap SHA 7e62f753 deployed but its separate paper-analysis canary failed at cancel_start, with no newsroom journey evidence. Layer 32 remains scripted_passed with 38/38 criteria covered; the signed-in newsroom Tier-2/3 journey is still pending, with no local deploy, reset, OAuth or live credential mutation. Lessons and all evaluator rounds are archived under the L32-005 convergence record.",
+      "since_baseline": false
+    }
+  ],
+  "capabilities": [
+    {
+      "layer": 0,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "User signs up, installs daemon, runs looplia-run connect, types ls -la, sees directory listing. Also: looplia-run exec returns structured output. Resize works.",
+      "completed_at": "2026-04-07",
+      "source": "layer_gates[layer=0]"
+    },
+    {
+      "layer": 0.5,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Landing page renders with install instructions. Auth pages are polished and responsive. Dashboard shows daemon detail with connection status. Daemon connects to relay without frame errors. CLI authenticates and lists daemons successfully.",
+      "completed_at": "2026-04-07",
+      "source": "layer_gates[layer=0.5]"
+    },
+    {
+      "layer": 1,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "User launches agent container from looplia.run, opens Ghostty web terminal, interacts with Pi-Mono agent, agent executes commands on remote daemon via looplia-run. Blocked command returns rejection. Audit log shows command history.",
+      "completed_at": "2026-04-09",
+      "source": "layer_gates[layer=1]"
+    },
+    {
+      "layer": 2,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "User opens /dashboard/agent, asks 'what machines do I have?' — agent calls list_daemons and renders DaemonList. User asks 'run uname -a on <daemon>' — agent calls run_shell, output renders in TerminalCard. User clicks Open Terminal handoff — lands on /dashboard/terminal connected to the right daemon. Audit log queries via get_audit_log render in AuditTable. /dashboard/terminal still works for direct terminal use.",
+      "completed_at": "2026-05-04",
+      "source": "layer_gates[layer=2]"
+    },
+    {
+      "layer": 4,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Agent email — inbound + outbound through LoopliaAgent. User creates <user-slug>-default@looplia.run, an external Gmail account sends a test message (with attachment) to the alias, the inbox row appears in the dashboard with parsed body + downloadable attachment, user clicks Reply, the reply lands in Gmail in the original thread, Gmail 'Show original' confirms SPF=pass + DKIM=pass + DMARC=pass. HMAC reply-routing header on outbound roundtrips back to the correct LoopliaAgent. Spam-score header captured.",
+      "completed_at": "2026-05-27T10:13:59Z",
+      "source": "layer_gates[layer=4]"
+    },
+    {
+      "layer": 4.5,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "External agent surface. (a) Dashboard issues an aelk_ API key scoped to <slug>-bot@looplia.run with email:send + email:read; (b) Claude Code with the Looplia MCP installed lists + sends + replies, send_email triggers Claude Code's destructive-action confirmation prompt; (c) `looplia email send/read --json | jq` and `curl POST /v1/email/messages` succeed with the same key; (d) a webhook registered for email.received fires within 5s of delivery, X-Looplia-Signature verifies, replay-window (>5min) is rejected. Per-key rate limit + per-mailbox daily quotas enforced (429 on overflow). Scope mismatch returns 403.",
+      "completed_at": "2026-05-29",
+      "source": "layer_gates[layer=4.5]"
+    },
+    {
+      "layer": 8,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Self-improving loop E2E (scripted + prod dogfood): same task class 3x -> review authors ONE umbrella skill -> loaded and used on the 4th; review-run tool denial at beforeToolCall; cadence counters fire/no-fire; daily budget exhaustion; over-cap consolidation in review run only; every learning event in the observability feed; idle agent schedules nothing.",
+      "completed_at": "2026-06-10",
+      "source": "layer_gates[layer=8]"
+    },
+    {
+      "layer": 9,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "L9a work system E2E (scripted + 2-agent prod dogfood): assign -> heartbeat -> checkout -> mandatory comment -> done; double-trigger dedup; daemon-offline runtime_offline + rollback in_progress->todo; plan_only -> <=2 continuations -> escalation comment; manual rerun cancels in-flight + fresh session; dashboard approval resolution wakes assignee. Gate feeds the L9 calibration checkpoint and gates L9b.",
+      "completed_at": "2026-06-10",
+      "source": "layer_gates[layer=9]"
+    },
+    {
+      "layer": 10,
+      "gate_status": "scripted_passed",
+      "tense": "EXP",
+      "settles_on": "layer 10 human acceptance run",
+      "definition": "Company context E2E (scripted + real Notion/Drive dogfood): agent grounds an answer on a mounted page unseen this session; ACL-denied agent cannot list/read the mount; warmed glob within turn budget (no subrequest exhaustion); source edit -> fingerprint invalidation -> fresh read; OAuth refresh survives DO eviction.",
+      "completed_at": null,
+      "source": "layer_gates[layer=10]"
+    },
+    {
+      "layer": 10.5,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Company surface E2E (seed + scripted + prod dogfood): seed.sh idempotently provisions the test-user company fixture; pre-existing user gains the company agent via the ensureDefaultAgent backfill; Company sidebar section renders (company agent pinned, not duplicated in roster); /dashboard/company Tier 1 usable at 375px and Tier 2 office renders on desktop reflecting live snapshot state; node assign/conflict/unassign round-trip; representative dialogs top-anchored on mobile + desktop viewports.",
+      "completed_at": "2026-06-11",
+      "source": "layer_gates[layer=10.5]"
+    },
+    {
+      "layer": 11,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "COO control plane E2E (scripted + prod dogfood): chat the company agent into assigning a task → root company_task with truthful createdBy → assignee heartbeat-completes with a comment → run transcript readable via work.run.transcript; tool-gating matrix holds (worker agents and delegated children of the company agent see no COO tools); missing_parent invariant intact for workers; /company/wiki write→read round-trip with wildcard ACL and non-company write rejected at the adapter; run feed paginates company-wide.",
+      "completed_at": "2026-06-12",
+      "source": "layer_gates[layer=11]"
+    },
+    {
+      "layer": 11.5,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Cockpit IA E2E at 390px portrait AND desktop (scripted + agent-browser prod dogfood): every bottom tab reaches its surface with correct active state; sidebar shows COMPANY above AGENTS, Coordination gone, Skills in the right inspector; /dashboard/audit redirects to Company→Activity and both sub-tabs paginate; Context tab round-trips mount create+delete+ACL (wiki mount not deletable); board drag respects the legal-transition whitelist (In Progress rejects drops) and live run chips appear; a real task's Run pane replays its transcript with files-produced; all dialogs (incl. AlertDialog) top-anchored; ux-flow calibration verdict captured.",
+      "completed_at": "2026-06-12",
+      "source": "layer_gates[layer=11.5]"
+    },
+    {
+      "layer": 12,
+      "gate_status": "scripted_passed",
+      "tense": "EXP",
+      "settles_on": "layer 12 human acceptance run",
+      "definition": "Voice E2E (scripted + prod dogfood): scripted — voiceTurn bridge frames (delta/tool/error/done) + server-side history + voice metadata + per-thread busy latch + ticket gate matrix + guardrail state machine with faked clocks, e2e suite at known-red baseline zero-delta. Prod dogfood (real mic on looplia.run) — spoken Q&A with per-stage latency recorded; daemon tool turn speaks a status line then the result (long run → handoff phrase, result in thread); barge-in stops audio <300ms with the run persisting; idle/cap hangups; voice chips in thread; mic absent on company agent/email/touch; performance-quality + ux-flow calibration verdicts captured by listening on the real call.",
+      "completed_at": null,
+      "source": "layer_gates[layer=12]"
+    },
+    {
+      "layer": 18,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Set a north star -> persists company_north_star + fixed-id anchor task; enable the loop at the 300s floor -> exactly ONE goal-pursuit task_run for 'default' per tick (overlapping ticks coalesce, no second alarm) with a mandatory comment; a productive cycle delegates to a NON-default worker agent or raises an approval; MAX_TICKS caps minting; pause stops new ticks while in-flight finishes; disable cancels the interval; buildNorthStarTrigger round-trips through parseHeartbeatTrigger and a non-anchor task still routes to plain runHeartbeatTurn.",
+      "completed_at": "2026-06-17",
+      "source": "layer_gates[layer=18]"
+    },
+    {
+      "layer": 18.5,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Capture model usage (run-stream) + accumulate per run + write a cost row keyed to task_run+period; lowering the budget below period spend auto-pauses the loop (paused_reason=budget) + raises exactly one idempotent kind=budget approval; resume requires clearing pause; a goal turn crossing the budget mid-run aborts at the next step boundary; non-goal turn output unchanged.",
+      "completed_at": "2026-06-26",
+      "source": "layer_gates[layer=18.5]"
+    },
+    {
+      "layer": 19,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Coordination is a property of shared state: a 2nd companyHeartbeat with the north star's work already covered creates ZERO new tasks; listTasksByGoal(anchor) returns the linked set; createTask dedupes on (goal_id, normalized title); goal-pursuit acts only on gaps; a tick with all goal work covered is a NO-OP (Decision B — no completion state machine / no self-pause); the auto-injected shared-org operating-state stays under cap and does NOT grow across N ticks (anti-context-rot); the full plan lives at /company/wiki/company-plan.md and an employee turn shows the concise state.",
+      "completed_at": "2026-06-18",
+      "source": "layer_gates[layer=19]"
+    },
+    {
+      "layer": 21,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "The autonomy-first surface works end-to-end: agent.trajectory.list returns a per-agent UNIFIED timeline merging run-store entries (agent_run: heartbeat/autonomous/work/delegated) and chat threads (assistant_messages) newest-first under one normalized cross-store keyset cursor; agent.trajectory.detail returns full steps including the model's ENABLED + captured per-step reasoning + tool calls + files (a live heartbeat shows NON-EMPTY reasoning, not just a mock). Web: the Agents page shows the per-agent trajectory (no chat), the left sidebar is exactly Company / Agent / Settings, and a row opens a detail modal. The Company page hosts a single #general chat (agent=default, thread=company-general) routed FRONT-DESK to the company agent Looplia (single target; @mention->employee + agents-meeting deferred to Layer 22), plus the moved work/messaging/activity surfaces + a Company Vision panel reusing companyAutopilot.northStar. Memory/company-context (assemble.ts, /org, /company/wiki, manage_memory, L19 anti-context-rot) unchanged — trajectory only surfaces those writes.",
+      "completed_at": "2026-06-20",
+      "source": "layer_gates[layer=21]"
+    },
+    {
+      "layer": 23,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "The redesign works end-to-end: ONE unified full-bleed app shell replaces the two divergent pages; a vertical sidebar-TOP mode list (Company/Agents) switches the center surface and switching modes does NOT remount the COO chat; the top horizontal AGENTS/COMPANY nav is gone; Settings is in the sidebar footer. Company mode renders former tabs as sidebar items (Chat/Mission/Overview/Context/Activity) full-bleed, with VISION+AUTOPILOT merged into one Mission surface and the chat labeled 'Chat (Looplia · COO)' as the default surface. COO MODEL: the company agent calls a set_company_mission tool to write the north star/objectives to the Mission single source of truth, which the chat context AND the heartbeat read (so the chat reports the persisted north star — the L21 incoherence is fixed). Agents mode keeps the trajectory with the 21.5 behaviors (reasoning expanded, two-line rows, live streaming). Default landing = Company -> Chat. Mobile = sidebar drawer + full-screen detail sheet. Memory/company-context unchanged.",
+      "completed_at": "2026-06-24",
+      "source": "layer_gates[layer=23]"
+    },
+    {
+      "layer": 24,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "A user hires an employee agent ENTIRELY inside Talk-to-Looplia: asking Looplia to hire produces ONE inline HireApprovalCard (json-render via render_ui) bound to a real pending approval; Approve provisions the employee within seconds WITH THE LOOP OFF (P0-B) and the card shows the hired/first-task state; no leaving the chat. The duplicate approval surfaces are consolidated to one PendingApprovalsList (Work-board strip removed) reusing the same card + resolve path; the manual create-agent dialog surfaces errors instead of closing silently (P0-C). Scripted (vitest-pool-workers): resolve(approve)->provision with loop OFF, idempotent double-resolve, render_ui round-trip, catalog Zod rejects a malformed spec, card dedup by approvalId. Prod dogfood (agent-browser, fresh account): the full inline-hire happy path.",
+      "completed_at": "2026-06-28",
+      "source": "layer_gates[layer=24]"
+    },
+    {
+      "layer": 25,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Hire-vertical polish + generative-UI durability (the Layer 24 follow-ups). (1) Asking Looplia to hire a specific role provisions an employee whose blueprint (name/slug/purpose) reflects the REQUESTED role even when the model omits the blueprint arg — derived server-side from the triggering message, not a generic 'Assistant'; two different role requests yield two distinct employees; no-role falls back to the FIX-HIRE-002 generic synthesis with the single-pending-approval idempotency preserved. (2) An inline render_ui/HireApprovalCard SURVIVES a full page reload and re-queries live status (tool-call+result parts now persist on the outbound assistant turn and rehydrate via threadRowsToMessages -> setMessages); byte-stable for non-tool turns; an unresolved approvalId still renders inert (FIX-HIRE-004 guard). (3) The stale unit reds (COO 6-vs-7 tools, advisory blueprint_mismatch) are refreshed so the suite is a trustworthy signal. Scripted (do-agent bun + web bun + e2e vitest-pool-workers): server-derived role blueprint from sparse context, two-distinct-roles, generic fallback + idempotency; render_ui round-trip persisted + rehydrated toolCalls message, byte-stable non-tool turns; refreshed COO-tool-count + advisory-blueprint assertions. Prod dogfood (agent-browser, test@looplia.run): hire a named role -> role-named employee in the roster; render a hire card -> hard reload -> card still there + actionable.",
+      "completed_at": "2026-06-30",
+      "source": "layer_gates[layer=25]"
+    },
+    {
+      "layer": 26,
+      "gate_status": "scripted_passed",
+      "tense": "EXP",
+      "settles_on": "layer 26 human acceptance run",
+      "definition": "Autonomous goal-owning employees + memory-through-execution (docs/research-note/18+19+20). Tier-1 scripted (vitest-pool-workers + do-agent bun): (EXEC) an owned-goal anchor assigned to an employee routes its wake to a goal-pursuit-style turn (reconciling its own goal tree) while the north-star anchor still routes the COO (regression); the scheduler fan-out mints exactly one coalesced `schedule` wake per active goal-owner (overlapping ticks no-op via the one-active-run index); #needsSupervision throttles the COO (no COO wake when covered); per-owned-goal cadence (awaiting_reply/paused not ticked); buildTurnTrigger renders each RunTrigger kind + parseHeartbeatTrigger round-trip; an inbound reply wakes the owner with email_received; an employee owned-goal turn creates a scoped subtask but cannot hire/set-mission/create-root. (MEM) an autonomous heartbeat/task turn that learns a durable fact triggers a consolidation/self-review pass over its agent_run_step window and writes to the right relationship memory (or authors a skill); an external counterparty keyed by channel id has a durable home and is retrieved into the current task's turn. Tier-2/3 dogfood (https://looplia.run): re-run the reader-outreach campaign; a schedule-triggered episode-2 (no inbound reply) autonomously advances the employee's owned goal in the counterparty's STORED language/cadence, without re-reading the thread and without a COO relay each tick.",
+      "completed_at": "2026-07-02T10:02:00Z",
+      "source": "layer_gates[layer=26]"
+    },
+    {
+      "layer": 31,
+      "gate_status": "passed",
+      "tense": "IS",
+      "settles_on": null,
+      "definition": "Hire paper-researcher@v1 and startup-writer@v1 through exact BlueprintV2 approvals. Both lock the shared newsroom core plus distinct role packs, qualify without manual setup, and become routable only after pass. A failed/stale qualification receives zero recurring/assignment wakes; a Data Analyst requirement produces capability_gap rather than generic fallback. Real scholarly compute is L32, authority L33 and publication L39.",
+      "completed_at": "2026-07-18T10:44:00Z",
+      "source": "layer_gates[layer=31]"
+    },
+    {
+      "layer": 32,
+      "gate_status": "scripted_passed",
+      "tense": "EXP",
+      "settles_on": "layer 32 human acceptance run",
+      "definition": "A bounded beat/source scan autonomously produces and prioritizes a pitch; qualified Paper Researcher resolves current scholarly status and produces a versioned ClaimLedger/ResearchDossier with reproducible Sandbox evidence; Startup Writer produces a claim-linked reader-useful article/package with no Sandbox/generic-shell/daemon route; an independent researcher fact-check catches a seeded overclaim and binds the exact draft.",
+      "completed_at": null,
+      "source": "layer_gates[layer=32]"
+    }
+  ],
+  "cost": {
+    "total_usd": 0,
+    "instrumented": false,
+    "by_layer_count": 0,
+    "by_story_count": 25,
+    "note": "cost plane declared but unwired"
+  },
+  "modules": {
+    "declared_count": 32,
+    "path_bound_count": 0,
+    "names": [
+      "api",
+      "auth",
+      "relay",
+      "protocol",
+      "daemon",
+      "cli",
+      "web",
+      "looplia-agent",
+      "agent-memory",
+      "agent-self-improve",
+      "company-work-system",
+      "company-context",
+      "company-formation-and-hiring",
+      "connector-observer",
+      "fde-transformation-cockpit",
+      "company-interaction-canvas",
+      "email-ingress",
+      "email-outbound",
+      "email-api",
+      "email-webhooks",
+      "email-cli",
+      "voice",
+      "employee-capability-foundation",
+      "professional-execution-plane",
+      "professional-learning-loop",
+      "company-deliberation",
+      "authority-kernel",
+      "company-event-workflow-backbone",
+      "workload-identity-secrets-execution",
+      "company-assurance-incident-ops",
+      "data-governance-continuity",
+      "business-system-adapters"
+    ]
+  },
+  "code_graph": {
+    "nodes": 21,
+    "edges": 75,
+    "apps": 3,
+    "packages": 17,
+    "name_overlap": 1,
+    "tool": "scan-workspace.mjs (package.json workspace graph, deterministic)",
+    "commit": "65e359c6"
+  },
+  "delta": {
+    "first_run": true,
+    "commits_since_baseline": null,
+    "status_changes": [],
+    "changelog_new": 0
+  }
+}
diff --git a/docs/human-alignment/example-looplia/manifest.json b/docs/human-alignment/example-looplia/manifest.json
new file mode 100644
index 0000000..bc45406
--- /dev/null
+++ b/docs/human-alignment/example-looplia/manifest.json
@@ -0,0 +1,17 @@
+{
+  "schema_version": 1,
+  "generated": "2026-07-25T0308Z",
+  "commit": "65e359c6",
+  "output": "brief-2026-07-25T0308Z-65e359c6.html",
+  "facts_sha256": "028ac7ee9dea5970791e4020da8a20699b17e3712d1323bc440cb427244b271f",
+  "artifacts": [
+    "aep-loop",
+    "architecture-declared",
+    "architecture-overview",
+    "architecture-packages",
+    "story-states"
+  ],
+  "degraded": [],
+  "content_sha256": "05571cf8e5bbcee886089ad00280445c65e0c0c6d1f08d5f1a42371c22ab01f6",
+  "history": []
+}
diff --git a/evals/skill-behavior-parity.json b/evals/skill-behavior-parity.json
index 65e3986..eae1817 100644
--- a/evals/skill-behavior-parity.json
+++ b/evals/skill-behavior-parity.json
@@ -204,6 +204,20 @@
         "references/workspace-hook.md"
       ],
       "observed_postcondition": "Audit detects layout drift, confirmed mechanical fixes converge idempotently, and ambiguous copies fail closed."
+    },
+    {
+      "skill": "aep-human-alignment",
+      "scenario": "Render a real consumer's product-context.yaml (396 stories, 41 layer gates, 21 workspace packages) into a one-page brief, end to end: derive, scan, author, audit, deliver.",
+      "result": "pass",
+      "loaded_references": [
+        "references/guideline.md",
+        "references/derivation.md",
+        "references/presentation.md",
+        "references/checklist.md",
+        "references/attention-set.md",
+        "references/drift-facts.md"
+      ],
+      "observed_postcondition": "facts JSON validated against facts.schema.json; all five archify artifacts reached validate-green and delivered inside the two-round receipt bound; audit.mjs passed standalone; the assembled 3.2 MB single file resolved all 22 data-fact bindings with zero unresolved, mounted three srcdoc frames, and recorded a content SHA-256 in manifest.json matching the delivered bytes."
     }
   ]
 }
diff --git a/evals/skill-routing.json b/evals/skill-routing.json
index c2b77ef..5689dff 100644
--- a/evals/skill-routing.json
+++ b/evals/skill-routing.json
@@ -222,6 +222,24 @@
       "kind": "boundary",
       "prompt": "Monitoring already produced one concrete observation; classify that learning and decide which product phase changes.",
       "expected": "aep-reflect"
+    },
+    {
+      "id": "human-alignment-direct",
+      "kind": "direct",
+      "prompt": "Give me a one-page brief of where this project stands, what is waiting on me, and where reality drifted from the plan.",
+      "expected": "aep-human-alignment"
+    },
+    {
+      "id": "human-alignment-vs-envision",
+      "kind": "boundary",
+      "prompt": "The plan file already exists and is current; render its state as a project status one-pager somebody new could read cold.",
+      "expected": "aep-human-alignment"
+    },
+    {
+      "id": "human-alignment-vs-watch",
+      "kind": "boundary",
+      "prompt": "Do not ingest telemetry or open a monitoring tick — just render the plan file's current state into a human-readable brief.",
+      "expected": "aep-human-alignment"
     }
   ]
 }
diff --git a/frontier-fixed.png b/frontier-fixed.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e2fdd8744fa3c917955fb65f52f1281acb2fccd
GIT binary patch
literal 121514
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	&>0d^95ZG17j;~;4kti1
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

literal 0
HcmV?d00001

diff --git a/scripts/build-skills.sh b/scripts/build-skills.sh
index 0d16eab..35cb7a6 100755
--- a/scripts/build-skills.sh
+++ b/scripts/build-skills.sh
@@ -63,6 +63,20 @@ if [ ! -d "$SHARED" ]; then
   exit 1
 fi
 
+# Consumers of the shared corpus: every skill directory in the repo, whether it
+# sits under skills/product-context/ (the original category) or directly under
+# skills/ as a standalone top-level skill. A directory is a skill iff it holds a
+# SKILL.md, which excludes the category dirs and _shared itself. Standalone
+# skills need this because the `skills` CLI installs one directory at a time —
+# a skill that reads references/attention-set.md must carry its own copy.
+consumer_dirs() {
+  local d
+  for d in "$PC"/*/ "$REPO"/skills/*/; do
+    [ -f "$d/SKILL.md" ] || continue
+    printf '%s\n' "$d"
+  done | sort -u
+}
+
 # Desired managed files (relative paths within the shared dir) for one consumer.
 desired_files() {
   local skillmd="$1" shared="$2"
@@ -139,9 +153,8 @@ preflight_destinations() {
   local skill_dir name skillmd shared src dst desired recorded rel seen marker
   local failures=0
 
-  for skill_dir in "$PC"/*/; do
+  while IFS= read -r skill_dir; do
     name="$(basename "$skill_dir")"
-    [ "$name" = "_shared" ] && continue
     skillmd="$skill_dir/SKILL.md"
     [ -f "$skillmd" ] || continue
 
@@ -183,7 +196,7 @@ preflight_destinations() {
         fi
       done <<< "$desired"
     done
-  done
+  done <<< "$(consumer_dirs)"
 
   [ "$failures" -eq 0 ] || {
     echo "ERROR: $failures unsafe generated-resource destination(s); nothing was changed." >&2
@@ -198,9 +211,8 @@ WROTE=0
 CONFLICT=0
 CHANGED_FILES=""
 
-for skill_dir in "$PC"/*/; do
+while IFS= read -r skill_dir; do
   name="$(basename "$skill_dir")"
-  [ "$name" = "_shared" ] && continue
   skillmd="$skill_dir/SKILL.md"
   [ -f "$skillmd" ] || continue
 
@@ -307,7 +319,7 @@ $desired"
       WROTE=$((WROTE + 1))
     fi
   done
-done
+done <<< "$(consumer_dirs)"
 
 # Stage exactly what this run changed (lefthook's stage_fixed only re-stages
 # files that were already staged, so the hook passes --stage instead).
diff --git a/skills/human-alignment/SKILL.md b/skills/human-alignment/SKILL.md
new file mode 100644
index 0000000..21fc2e8
--- /dev/null
+++ b/skills/human-alignment/SKILL.md
@@ -0,0 +1,152 @@
+---
+name: aep-human-alignment
+description: >-
+  Renders product-context.yaml into a one-page HTML project brief: where we are,
+  what needs a human, where reality drifted. Use for project brief, status
+  one-pager, or onboarding a cold reader; not planning (/aep-envision).
+---
+
+# Human Alignment
+
+Turn `product-context.yaml` into **one self-contained HTML page** that answers the
+three questions a returning human actually has: _where are we, what needs me,
+where did reality drift from intent?_
+
+Numbers are derived by code. Prose is written by you. Both are labeled, and an
+independent audit refuses to ship a page that blurs the line.
+
+Rationale and the decisions behind every rule:
+[`docs/decisions/human-alignment.md`](https://github.com/memorysaver/agentic-engineering-patterns/blob/main/docs/decisions/human-alignment.md).
+
+## The contract in one paragraph
+
+Every read is a **first read**. Each surfaced item is a plain-language sentence
+first — what happened, to what, why the reader cares — with the system
+identifier demoted to a small provenance anchor beneath it. Facts are unchipped;
+only non-facts carry a tense chip. **You never author a number.**
+
+## Steps
+
+Each phase ends in a checkable postcondition. Do not start a phase whose
+predecessor's postcondition is unmet.
+
+### 0 · Preflight
+
+`product-context.yaml` must exist (else stop and point to `/aep-envision`). Read
+`docs/human-alignment/manifest.json` for the delta baseline.
+
+→ _baseline commit known, or first run declared._
+
+### 1 · Derive
+
+```bash
+node scripts/derive.mjs --context product-context.yaml --repo . \
+  --out docs/human-alignment/facts.json [--code-graph docs/human-alignment/code-graph.json]
+```
+
+The facts JSON is the **only legal source of numbers**. It validates against
+`scripts/facts.schema.json` or the run stops.
+
+→ _facts JSON exists and validates._
+
+### 1.5 · Scan (architecture)
+
+```bash
+node scripts/scan-workspace.mjs --repo . --out docs/human-alignment/code-graph.json
+node scripts/arch-rules.mjs --code-graph docs/human-alignment/code-graph.json \
+  --context product-context.yaml --out-dir <build-dir>
+for tier in overview packages declared; do
+  node scripts/receipt-consumer.mjs --type architecture \
+    --in <build-dir>/architecture-$tier.architecture.json --out <build-dir>/architecture-$tier.html
+done
+node scripts/receipt-consumer.mjs --type workflow  --in assets/aep-loop.workflow.json      --out <build-dir>/aep-loop.html
+node scripts/receipt-consumer.mjs --type lifecycle --in assets/story-states.lifecycle.json --out <build-dir>/story-states.html
+```
+
+Re-run `derive.mjs` with `--code-graph` afterwards so the declared-vs-actual
+drift fact is included. No workspace manifest, or no archify CLI (exit 3)? The
+architecture view **degrades and says so on the page** — it never blocks.
+
+→ _artifacts delivered `code-verified`, or the view is marked degraded._
+
+### 2 · Author
+
+Copy `assets/template.html` and fill its `{{SLOTS}}`. **Read the template's
+contract comment before writing a single section** — it is the only source of
+CSS class names and of the `data-fact` binding convention.
+
+The authoring rules are in [`references/guideline.md`](references/guideline.md).
+The five that fail an audit fastest:
+
+1. **Answer first** — every section opens with one plain sentence that _is_ the
+   section's conclusion.
+2. **Translate** — story titles and changelog entries never surface verbatim;
+   re-author each as a consequence sentence bound to its id in the anchor.
+3. **No naked numbers** — every number is `data-fact`, inside a sentence that
+   states its consequence.
+4. **Fold the queue** — backlog collapses to one sentence per layer, full list
+   behind a disclosure.
+5. **Never chip a fact** — an unchipped page is a page of facts; diluting that
+   destroys the only trust gauge the reader has.
+
+→ _every section rendered or stamped; no `{{SLOT}}` left._
+
+### 3 · Audit
+
+```bash
+node scripts/audit.mjs --html <authored.html> --facts docs/human-alignment/facts.json \
+  --template assets/template.html
+```
+
+Failures are structured receipts (`code` · `subject` · `evidence` ·
+`supportedFixes`). Apply a **listed** fix and re-run. Never guess, and never
+exceed **two** correction rounds — a third failure is reported, not retried.
+Then walk the judgment checks in [`references/checklist.md`](references/checklist.md).
+
+→ _audit passes; judgment checks walked._
+
+### 4 · Deliver
+
+```bash
+node scripts/assemble.mjs --authored <authored.html> --facts docs/human-alignment/facts.json \
+  --artifacts <build-dir> --out-dir docs/human-alignment --keep 3
+```
+
+Writes `brief-<date>T<time>Z-<shorthash>.html`, updates `manifest.json`
+(appending the prior record to `history[]`), and prunes every brief beyond the
+newest three. Report the path and the delta summary in conversation — the owner
+opens the file.
+
+→ _new file exists; its name's hash equals HEAD; ≤ 3 briefs remain._
+
+## What the framework specs own
+
+Two derivations are **framework vocabulary**, not skill-private logic. Do not
+re-invent them here:
+
+- [`references/attention-set.md`](references/attention-set.md) — what needs a
+  human, its priority order, and the per-predicate schema-tolerance rule.
+- [`references/drift-facts.md`](references/drift-facts.md) — the five drift
+  derivations. Hand-authored drift is banned: when nothing derives, the row is
+  silent, not fabricated.
+
+`derive.mjs` implements both. If a predicate's fields are absent, it is skipped
+**and recorded** — an empty attention set is only trustworthy when the skip list
+is empty too, and the page must say which it is.
+
+## Boundaries
+
+- **Gates**: only `passed` yields an unchipped capability. A `scripted_passed`
+  gate may appear **only** under an `EXP` chip naming the acceptance run that
+  would settle it. Anything lower does not reach the product band.
+- **Language**: one file per run in the owner's language (an invocation
+  parameter, defaulting to the repo's working language). System identifiers stay
+  untranslated in anchors.
+- **Not this skill**: planning (`/aep-envision`), decomposition (`/aep-map`),
+  design theory (`/aep-design-lens`).
+
+## Layout notes
+
+Presentation bounds, the glance gate, and the degrade ladder live in
+[`references/presentation.md`](references/presentation.md). The field map from
+YAML path to fact is in [`references/derivation.md`](references/derivation.md).
diff --git a/skills/human-alignment/assets/aep-loop.workflow.json b/skills/human-alignment/assets/aep-loop.workflow.json
new file mode 100644
index 0000000..20212ec
--- /dev/null
+++ b/skills/human-alignment/assets/aep-loop.workflow.json
@@ -0,0 +1,99 @@
+{
+  "schema_version": 1,
+  "diagram_type": "workflow",
+  "meta": {
+    "title": "How the project moves",
+    "subtitle": "The AEP loop · dispatch and wrap write the plan file · this brief is derived from it",
+    "output": "aep-loop.html",
+    "quality_profile": "standard"
+  },
+  "lanes": [
+    { "id": "loop", "label": "The six-step loop" },
+    { "id": "data", "label": "Plan file and outputs" }
+  ],
+  "mainPath": ["envision", "map", "dispatch", "build", "wrap", "reflect"],
+  "nodes": [
+    {
+      "id": "envision",
+      "lane": "loop",
+      "col": 0,
+      "type": "frontend",
+      "label": "Envision",
+      "sublabel": "ENVISION",
+      "width": 60
+    },
+    {
+      "id": "map",
+      "lane": "loop",
+      "col": 1,
+      "type": "frontend",
+      "label": "Map",
+      "sublabel": "MAP",
+      "width": 60
+    },
+    {
+      "id": "dispatch",
+      "lane": "loop",
+      "col": 2,
+      "type": "backend",
+      "label": "Dispatch",
+      "sublabel": "DISPATCH",
+      "width": 60
+    },
+    {
+      "id": "build",
+      "lane": "loop",
+      "col": 3,
+      "type": "backend",
+      "label": "Build",
+      "sublabel": "BUILD",
+      "width": 60
+    },
+    {
+      "id": "wrap",
+      "lane": "loop",
+      "col": 4,
+      "type": "backend",
+      "label": "Wrap",
+      "sublabel": "WRAP",
+      "width": 60
+    },
+    {
+      "id": "reflect",
+      "lane": "loop",
+      "col": 5,
+      "type": "frontend",
+      "label": "Reflect",
+      "sublabel": "REFLECT",
+      "width": 60
+    },
+    {
+      "id": "context",
+      "lane": "data",
+      "col": 2,
+      "type": "database",
+      "label": "Plan file",
+      "sublabel": "CONTEXT"
+    },
+    {
+      "id": "view",
+      "lane": "data",
+      "col": 5,
+      "type": "frontend",
+      "label": "This brief",
+      "sublabel": "VIEW"
+    }
+  ],
+  "edges": [
+    { "id": "e1", "from": "envision", "to": "map" },
+    { "id": "e2", "from": "map", "to": "dispatch", "route": "bottom-channel" },
+    { "id": "e3", "from": "dispatch", "to": "build" },
+    { "id": "e4", "from": "build", "to": "wrap", "route": "bottom-channel" },
+    { "id": "e5", "from": "wrap", "to": "reflect" },
+    { "id": "e6", "from": "reflect", "to": "envision", "label": "loop", "route": "bottom-channel" },
+    { "id": "e7", "from": "dispatch", "to": "context", "label": "writes", "route": "drop" },
+    { "id": "e8", "from": "wrap", "to": "context", "label": "writes", "route": "drop" },
+    { "id": "e9", "from": "context", "to": "view", "label": "derives", "variant": "emphasis" }
+  ],
+  "cards": []
+}
diff --git a/skills/human-alignment/assets/story-states.lifecycle.json b/skills/human-alignment/assets/story-states.lifecycle.json
new file mode 100644
index 0000000..b3ad7fa
--- /dev/null
+++ b/skills/human-alignment/assets/story-states.lifecycle.json
@@ -0,0 +1,119 @@
+{
+  "schema_version": 1,
+  "diagram_type": "lifecycle",
+  "meta": {
+    "title": "The five stages of a task",
+    "subtitle": "Story state machine · the sole definition of this brief's vocabulary · exceptions are markers, not stages",
+    "output": "story-states.html",
+    "quality_profile": "standard"
+  },
+  "lanes": [
+    { "id": "main", "label": "The normal path (the five cells beside every task row)" },
+    { "id": "exceptions", "label": "Exceptions · waiting on a human" }
+  ],
+  "states": [
+    {
+      "id": "pending",
+      "type": "start",
+      "label": "Pending",
+      "sublabel": "PENDING",
+      "lane": "main",
+      "col": 0,
+      "step": "01"
+    },
+    {
+      "id": "ready",
+      "type": "active",
+      "label": "Ready",
+      "sublabel": "READY",
+      "lane": "main",
+      "col": 1,
+      "step": "02"
+    },
+    {
+      "id": "in_progress",
+      "type": "active",
+      "label": "In progress",
+      "sublabel": "IN_PROGRESS",
+      "lane": "main",
+      "col": 2,
+      "step": "03"
+    },
+    {
+      "id": "in_review",
+      "type": "active",
+      "label": "In review",
+      "sublabel": "IN_REVIEW",
+      "lane": "main",
+      "col": 3,
+      "step": "04"
+    },
+    {
+      "id": "completed",
+      "type": "success",
+      "label": "Completed",
+      "sublabel": "COMPLETED",
+      "lane": "main",
+      "col": 4,
+      "step": "05"
+    },
+    {
+      "id": "blocked",
+      "type": "waiting",
+      "label": "Blocked",
+      "sublabel": "dependency failed",
+      "lane": "exceptions",
+      "col": 0
+    },
+    {
+      "id": "failed",
+      "type": "failure",
+      "label": "Failed",
+      "sublabel": "retries exhausted",
+      "lane": "exceptions",
+      "col": 1
+    },
+    {
+      "id": "deferred",
+      "type": "waiting",
+      "label": "Deferred",
+      "sublabel": "postponed by a human",
+      "lane": "exceptions",
+      "col": 2
+    }
+  ],
+  "transitions": [
+    { "id": "t1", "from": "pending", "to": "ready", "label": "deps done", "labelDy": -25 },
+    { "id": "t2", "from": "ready", "to": "in_progress", "label": "dispatched", "labelDy": -25 },
+    { "id": "t3", "from": "in_progress", "to": "in_review", "label": "PR open", "labelDy": -25 },
+    { "id": "t4", "from": "in_review", "to": "completed", "label": "verified", "labelDy": -25 },
+    { "id": "t5", "from": "pending", "to": "blocked", "route": "drop" },
+    { "id": "t6", "from": "in_progress", "to": "failed", "route": "drop" },
+    {
+      "id": "t7",
+      "from": "failed",
+      "to": "pending",
+      "label": "only a human may do this",
+      "variant": "security",
+      "route": "bottom-channel"
+    },
+    {
+      "id": "t8",
+      "from": "blocked",
+      "to": "pending",
+      "label": "unblocked",
+      "route": "bottom-channel"
+    }
+  ],
+  "cards": [
+    {
+      "dot": "amber",
+      "title": "Why \"needs you\" exists",
+      "items": [
+        "failed → pending is a transition only a human may run",
+        "blocked and deferred also wait on a person",
+        "this is where the Overview band's ask comes from"
+      ]
+    }
+  ]
+}
diff --git a/skills/human-alignment/assets/template.html b/skills/human-alignment/assets/template.html
new file mode 100644
index 0000000..1e4a7aa
--- /dev/null
+++ b/skills/human-alignment/assets/template.html
@@ -0,0 +1,853 @@
+<!doctype html>
+<html lang="{{LANG}}">
+  <head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <title>{{PROJECT}} · project brief
+    
+    
+    
+    
+    
+  
+  
+    
+
+ +
+ {{PROJECT}} · brief + + + layer + open + needs you + +
+ + +
+
+

Overview · the whole thing at a glance

+

{{PROJECT_TITLE}}

+

{{OVERVIEW_ANSWER_FIRST}}

+ +
+

{{PRIMER_ESSENCE}}

+

{{PRIMER_ANCHOR}}

+

Overview · unchanged since {{IDENTITY_STAMP}}

+
+ +
+

{{ASK_VERB}}

+

{{ASK_SENTENCE}}

+

{{ASK_HOW}}

+

{{ASK_ANCHOR}}

+
+ +

{{QUIET_ZONE}}

+

{{QUIET_ANCHOR}}

+ +
+

{{AWAY_HEADING}}

+

{{AWAY_NARRATIVE}}

+

{{AWAY_ANCHOR}}

+
+ +

+ Five cells = the five stages of a task; filled = reached. Exceptions are markers, not + stages — defined once in Engineering. Small type under a sentence is its source; you only + need it when checking. +

+
+
+ + +
+
+

Product · what it can do

+

{{PRODUCT_TITLE}}

+

{{PRODUCT_ANSWER_FIRST}}

+ +
+
+

{{SHIPPED_HEADING}}

+ {{SHIPPED_CAPABILITIES}} +
+
+

{{RECENT_HEADING}}

+ {{RECENT_CHANGES}} +
+
+

{{NEXT_HEADING}}

+ {{NEXT_CAPABILITIES}} +
+

Product · capability list unchanged since {{CAPABILITIES_STAMP}}

+
+ +

+ This list is derived from gates that reached passed; a gate that has only + passed its scripted run appears under an EXP chip naming the acceptance run that would + settle it. Nothing appears here on the strength of an unfinished gate. +

+
+
+ + +
+
+

Project · plan and progress

+

{{PROJECT_BAND_TITLE}}

+

{{PROJECT_ANSWER_FIRST}}

+ +
+
+ {{QUEUED_LAYERS}} +
+
+ + +
+
+

Project · ledger · facts that expire live here

+

{{LEDGER_TITLE}}

+

{{LEDGER_ANSWER_FIRST}}

+ +
+

{{MOVED_HEADING}}

+ {{MOVED_BODY}} +
+ +
+

{{DRIFT_HEADING}}

+ {{DRIFT_ROWS}} +
+ +

+ Every drift row is derived and cites its source — none is written from impression. + Unchipped = fact; EXP = an expectation, with the condition that would settle it. +

+
+
+ + +
+
+

Engineering · the system itself

+

{{ENGINEERING_TITLE}}

+

{{ENGINEERING_ANSWER_FIRST}}

+ +
+
+
+

{{ARCH_ANCHOR}}

+ {{ARCH_NOTE}} +

Engineering · architecture unchanged since {{ARCHITECTURE_STAMP}}

+
+ +
+

{{LIFECYCLE_HEADING}}

+

{{LIFECYCLE_INTRO}}

+
+
+

Engineering · loop and states unchanged since {{LIFECYCLE_STAMP}}

+
+ +
+

{{PROVENANCE_HEADING}}

+ {{PROVENANCE_BODY}} +

+
+
+
+ + + + + + + + diff --git a/skills/human-alignment/references/.aep-generated b/skills/human-alignment/references/.aep-generated new file mode 100644 index 0000000..e6c4696 --- /dev/null +++ b/skills/human-alignment/references/.aep-generated @@ -0,0 +1,3 @@ +# Managed by scripts/build-skills.sh — the files listed below are copies of skills/product-context/_shared/. Edit _shared/ and rebuild; every other file in this directory is skill-owned and never touched. +attention-set.md +drift-facts.md diff --git a/skills/human-alignment/references/attention-set.md b/skills/human-alignment/references/attention-set.md new file mode 100644 index 0000000..2759c87 --- /dev/null +++ b/skills/human-alignment/references/attention-set.md @@ -0,0 +1,100 @@ +# The Attention Set + +The canonical answer to **"what in this project needs a human right now?"** + +AEP scatters that answer across six places. Nothing in the framework collects +them, so every consumer that wants to escalate, alert, or report re-invents the +predicate list — and drifts. This spec is the single definition. It is a +**derived view**: computed on read, never stored. + +> Decision record: [`docs/decisions/human-alignment.md`](https://github.com/memorysaver/agentic-engineering-patterns/blob/main/docs/decisions/human-alignment.md) D7. +> First consumer: `/aep-human-alignment`. `/aep-autopilot` escalation and +> `/aep-watch` alerting re-point here in later releases. + +## Why derived, not stored + +- A story status describes **lifecycle position**, not human duty. A `failed` + story is failed _and_ needs a human; one enum cannot carry both. +- Half the signals are **not stories at all** (amendment log, object maps, + calibration, open questions). +- A stored copy of a derivable truth is a second source. Validation will not + catch it when it drifts — the OBS-4 shape, and this repo's most common bug + class. + +## The signal predicates + +Each row is a predicate over `product-context.yaml`, the action verb the human +sees, and the priority rank used to pick **the one ask**. + +| Rank | Signal | Predicate | Verb | +| ---- | ----------------- | ------------------------------------------------------------------ | ------------------ | +| 1 | Failed story | `stories[].status == "failed"` | `reset ▸` | +| 2 | Amendment pending | `architecture.amendment_log[].status == "pending"` | `approve ▸` | +| 3 | Awaiting review | `stories[].status == "in_review"`, not waived by `skip_human_eval` | `review ▸` | +| 4 | Calibration due | plan entry with no matching history entry (see below) | `/aep-calibrate ▸` | +| 5 | Draft object map | object-map `status == "draft"` | `/aep-model ▸` | +| 6 | Open question | `product.open_questions[]` non-empty | `answer ▸` | + +**Only a human may run `failed → pending`.** That is why rank 1 is rank 1: the +work is stopped and no agent can restart it. + +**`skip_human_eval`** lives at `layer_gates[].skip_human_eval` (`none` | +`backend` | `all`). A value of `all` waives every `in_review` story in that +layer; `backend` waives those whose story has no UI surface; `none` waives +nothing. An absent field waives nothing — but see Tolerance below, because +absent is not the same as `none`. + +**Calibration is derived from plan minus history, not from a status field.** +`calibration.plan[]` entries are `layer · dimensions · trigger`; there is no +`status` field to test, and never has been. A plan entry is **due** when: + +1. its `layer` is at or below the project's current layer, and +2. no `calibration.history[]` entry matches its `(layer, dimension)` pair. + +`trigger` is prose. Surface it next to the ask; never parse it. + +## The one ask + +A brief, an alert, or an escalation shows **one** item; the rest join a quiet +zone. Selection is deterministic — two runs at the same commit must choose the +same ask: + +1. lowest rank number wins (failed beats amendment beats in_review …); +2. ties break by layer order (lowest layer first); +3. remaining ties break by story/entry id, ascending, byte-wise. + +## Schema tolerance is per predicate + +Real consumer YAMLs diverge from the current schema in two different ways, and +handling only the first is how an attention set goes silently wrong: + +- a whole **section** may be absent (`product`, `opportunity`); +- a **field inside a present section** may be absent — a real consumer's + `architecture.amendment_log[]` entries carry only `date` and `summary`, though + the schema defines `status: pending | accepted | rejected`. + +Both cases mean the same thing: **the signal is not derivable in this schema.** + +A predicate whose fields are absent anywhere along its path is **skipped and +recorded**, never guessed and never treated as "no signal". Emit one record per +skipped predicate: + +```json +{ + "predicate": "amendment_pending", + "path": "architecture.amendment_log[].status", + "reason": "field absent in this schema version" +} +``` + +**An empty attention set is only trustworthy when the skip list is also empty.** +A consumer that reports "nothing needs you" while three predicates were skipped +is lying by omission. Say which of the two it is. + +## Field typing + +The predicate list says which items qualify; a surface usually also wants a +_why_ line. Type every field before rendering it: `business_value` is a numeric +score in real consumer YAMLs (and prose in others), so a why-line derivation +must require prose-typed sources and drop numeric ones rather than render a +meaningless `10`. diff --git a/skills/human-alignment/references/checklist.md b/skills/human-alignment/references/checklist.md new file mode 100644 index 0000000..242d679 --- /dev/null +++ b/skills/human-alignment/references/checklist.md @@ -0,0 +1,73 @@ +# Delivery Checklist + +`audit.mjs` runs the mechanical half. This file is the judgment half — the +checks a script cannot make. **P0 items block delivery.** + +## Receipt format + +Every failure, mechanical or judgment, is reported as a structured receipt: + +```json +{ + "code": "provenance/hardcoded-number", + "subject": { "number": "38" }, + "evidence": { "context": "…38 acceptance criteria, none verified…" }, + "supportedFixes": ["replace the literal with \">", "…"] +} +``` + +Apply a **listed** fix and re-run. Never invent a fix. Never exceed **two** +correction rounds — a third failure is reported to the owner, not retried. + +## P0 — mechanical (audit.mjs) + +- [ ] **No unfilled slot.** Every `{{SLOT}}` filled or deleted (`*_JSON` slots + are injected at assembly and exempt). +- [ ] **Number provenance.** Every `data-fact` path resolves in facts JSON, and + no digit appears in authored markup outside a `data-fact` element or an + anchor. +- [ ] **Class preflight.** Every class used exists in `assets/template.html`. + Authoring begins by reading its ` - - -
-
- -
- looplia-run · brief - - - layer - open - needs you - -
- - -
-
-

Overview · the whole thing at a glance

-

Looplia runs an AI company

-

Everything is moving except two repair jobs that only you can restart — they are the last things standing between the newsroom build-out and its sign-off.

- -
-

Looplia gives AI agents the shape of employees: each has its own mailbox, can take a call, and shares a task board, while a company layer assigns work, checks capability, and keeps a replayable record of every run. The build right now is a professional newsroom — researchers verify claims, writers produce articles where every sentence carries its citation.

-

No product-vision field exists in this plan file, so this paragraph is written by the agent, not derived. Adding one would let it become a derived fact. · schema gap: product / opportunity sections absent

-

Overview · unchanged since this generation

-
- -
-

Reset ▸

-

The post-deploy health check came back with a malformed error envelope, automatic repair has already given up, and the job is parked in a state only a person can move.

-

Read the failure log, set the task back to pending, then dispatch it again.

-

FIX-L32-CANARY-502-001 · stories[].status = failed · only a human may run failed → pending

-
- -

One more repair sits behind it — a sandbox supervisor that will not start cleanly under a fresh identity. Read both failure logs together before deciding which to restart first. Beyond those, items in total are waiting on you, and nearly all of them are taste checkpoints that were planned but never run.

-

FIX-L32-SUPERVISOR-START-001 · calibration.plan minus calibration.history · predicates could not be derived from this plan file at all

- -
-

Since the last brief

-

This is the first brief for this project, so there is no previous state to diff against. What the record shows instead is the newest stretch of work: the newsroom pipeline was wired end to end — the researcher re-verifies how current its sources are, the writer picks work off the formal assignment path and produces articles bound to their claims, and every run leaves a replayable trace. Two repairs opened in the same stretch and neither has closed.

-

changelog entries 2026-07-23 / 2026-07-24 · manifest.json absent at generation time = first run

-
- -

- Five cells = the five stages of a task; filled = reached. Exceptions are markers, not - stages — defined once in Engineering. Small type under a sentence is its source; you only - need it when checking. -

-
-
- - -
-
-

Product · what it can do

-

What works today

-

The company layer, the agent workforce, and the newsroom pipeline are all built; what is not yet signed off is whether the newsroom holds up under a human's judgement.

- -
-
-

Capabilities that have cleared acceptance

-

Across the build so far, acceptance runs have been signed off. Behind them sit the things you can actually use: agents that hold an identity and a mailbox, a shared task board they take work from, a company layer that grants and refuses capability, and a recorded, replayable trace of every run.

-

layer_gates[].status = passed · gates total

-
-
-

What changed for users recently

-

The newsroom went from parts to a production line: a researcher that re-checks whether its sources are still current, a writer that takes assignments through the formal routing path and emits articles whose every claim is linked to a source, and a fact-checker that reads the exact draft version rather than a summary of it.

-

changelog: L32-003 · L32-004 · L32-005 · L32-006 · L32-007 completed 2026-07-23/24

-
-
-

What the current stage will add

-

EXP → once the acceptance run for this stage passesThe newsroom's end-to-end run has passed its scripted check but not its human sign-off, so it is written here as an expectation rather than a fact. After it, the next stage is authority and governance: every action that reaches the outside world — publishing an article, for instance — has to clear a policy and permission gate first, which is what makes an autonomous newsroom safe to let out.

-

layer_gates[layer=32].status = scripted_passed (human acceptance not run) · L33-001…009 queued

-
-

Product · capability list unchanged since this generation

-
- -

- This list is derived from gates that reached passed; a gate that has only - passed its scripted run appears under an EXP chip naming the acceptance run that would - settle it. Nothing appears here on the strength of an unfinished gate. -

-
-
- - -
-
-

Project · plan and progress

-

Where the plan has got to

-

Of tasks, are finished and are still open — and all but two of the open ones are simply waiting their turn.

- -
-
-
-

What is queued behind this

-

Authority and governance comes next, then the stages that widen where material comes from and who is allowed to act on it. None of them has started; their tasks are written and waiting.

-
- Show every open task, stage by stage -
    -
  • Authority and governance — policy, permission lattice, decision receipts
  • -
  • Dynamic source plane — widening where the newsroom draws material from
  • -
  • Later stages — written, queued, not yet opened
  • -
-
-

stories[].status = pending, grouped by layer · pending, deferred

-
-
-
- - -
-
-

Project · ledger · facts that expire live here

-

What moved, and where reality drifted

-

places where the plan file and reality disagree — every one of them derived, none written from impression.

- -
-

What moved

-

The newsroom pipeline landed across five tasks in two days, each merged through its own pull request with an independent evaluation before it counted as done. Two repair jobs opened against the same stage and are still open.

-

changelog[] 2026-07-23 → 2026-07-24 · stories[].status transitions

-
- -
-

Where reality drifted

-
-

Work is marked done in stages that were never opened

-

Eight stages hold finished tasks while their acceptance run is still recorded as never started. Either the work outran its sign-off or the record was not kept up — both mean the control record no longer describes the project.

-

layer_gates[layer∈{2.5,3,5,7.5,13,27,28,29}].status = not_started with completed stories present

-
-
-

The code and the plan describe different systems

-

The code is packages joined by dependencies; the plan file describes conceptual modules, of which shares a name with anything that exists. No field binds a declared module to a source path, so the declared architecture cannot be checked against the code at all.

-

EXP → once modules[].paths lands in the schemaThe two accounts could then be reconciled automatically, and every declared dependency would become a lint rule with file and line evidence.

-

scan-workspace.mjs vs architecture.modules[] · modules carry a paths binding

-
-
-

Two repairs keep failing against the same subsystem

-

Both open repair jobs carry a failure log, which is the shape of a specification and an implementation disagreeing rather than a flaky run. Finished tasks that once failed are not counted here; their logs are history.

-

stories[].failure_logs on open stories only

-
-
-

One acceptance state is not in the vocabulary

-

A single stage records a sign-off state that the system does not define, which means the control file's own wording has started to drift.

-

layer_gates[layer=20].status = "completed" (defined states: not_started → scripted_passed → passed)

-
-
-

Spending is declared but never wired up

-

The cost plane totals zero while tasks carry free-text token notes, so this brief cannot tell you what the project has cost.

-

cost.total_usd = 0 · cost.by_story is prose, not numbers

-
-
- -

- Every drift row is derived and cites its source — none is written from impression. - Unchipped = fact; EXP = an expectation, with the condition that would settle it. -

-
-
- - -
-
-

Engineering · the system itself

-

What the system is made of

-

A deterministic scan reads the real package graph from the workspace manifest and groups it into domains; the plan file's own account of the architecture is shown beside it, and it does not match.

- -
-
-
-

scan-workspace.mjs → rules R1–R10 → archify validate/deliver · code-verified at package level · commit

-

The default view is the domain grouping. The deep-dive shows every package the rules kept; the declared narrative is the plan file's account, which is authored, not verified. Where the first two and the third disagree, that disagreement is recorded in the ledger above rather than quietly reconciled.

-

Engineering · architecture unchanged since this generation

-
- -
-

How the project moves, and the five stages of a task

-

These two diagrams are the only place this brief's vocabulary is defined. Solid lines are the normal path — the same five cells that sit beside every task row above. Dashed lines are exception markers. The step from failed back to pending is one only a person may take, which is why the top of this page has an ask at all.

-
-
-

Engineering · loop and states unchanged since this generation

-
- -
-

How to check any of this

-

Every number on this page is bound to a field in a machine-derived facts file; none was typed by the agent that wrote the prose. The small type under each statement names the field it came from, so any claim here can be traced back to the plan file or to the code scan. An independent audit re-checks those bindings before the page is written.

-

The audit could not derive of its signals from this plan file because the fields they need are absent. They are recorded as unavailable rather than reported as clear.

-

-
-
-
- - - - - - - - diff --git a/docs/human-alignment/example-looplia/brief-2026-07-25T0745Z-65e359c6.html b/docs/human-alignment/example-looplia/brief-2026-07-25T0745Z-65e359c6.html new file mode 100644 index 0000000..ab1df82 --- /dev/null +++ b/docs/human-alignment/example-looplia/brief-2026-07-25T0745Z-65e359c6.html @@ -0,0 +1,988 @@ + + + + + + looplia-run · project brief + + + + + + + +
+
+ +
+ looplia-run · brief + + + layer + open + needs you + +
+ + +
+
+

Overview · the whole thing at a glance

+

Looplia runs an AI company

+

Everything is moving except two repair jobs that only you can restart — they are the last things standing between the newsroom build-out and its sign-off.

+ +
+

Looplia gives AI agents the shape of employees: each has its own mailbox, can take a call, and shares a task board, while a company layer assigns work, checks capability, and keeps a replayable record of every run. The build right now is a professional newsroom — researchers verify claims, writers produce articles where every sentence carries its citation.

+

No product-vision field exists in this plan file, so this paragraph is written by the agent, not derived. Adding one would let it become a derived fact. · schema gap: product / opportunity sections absent

+

Overview · unchanged since this generation

+
+ +
+

Reset ▸

+

The post-deploy health check came back with a malformed error envelope, automatic repair has already given up, and the job is parked in a state only a person can move.

+

Read the failure log, set the task back to pending, then dispatch it again.

+

FIX-L32-CANARY-502-001 · stories[].status = failed · only a human may run failed → pending

+
+ +

One more repair sits behind it — a sandbox supervisor that will not start cleanly under a fresh identity. Read both failure logs together before deciding which to restart first. Beyond those, items in total are waiting on you, and nearly all of them are taste checkpoints that were planned but never run.

+

FIX-L32-SUPERVISOR-START-001 · calibration.plan minus calibration.history · predicates could not be derived from this plan file at all

+ +
+

Since the last brief

+

This is the first brief for this project, so there is no previous state to diff against. What the record shows instead is the newest stretch of work: the newsroom pipeline was wired end to end — the researcher re-verifies how current its sources are, the writer picks work off the formal assignment path and produces articles bound to their claims, and every run leaves a replayable trace. Two repairs opened in the same stretch and neither has closed.

+

changelog entries 2026-07-23 / 2026-07-24 · manifest.json absent at generation time = first run

+
+ +

+ Five cells = the five stages of a task; filled = reached. Exceptions are markers, not + stages — defined once in Engineering. Small type under a sentence is its source; you only + need it when checking. +

+
+
+ + +
+
+

Product · what it can do

+

What works today

+

The company layer, the agent workforce, and the newsroom pipeline are all built; what is not yet signed off is whether the newsroom holds up under a human's judgement.

+ +
+
+

Capabilities that have cleared acceptance

+

Across the build so far, acceptance runs have been signed off. Behind them sit the things you can actually use: agents that hold an identity and a mailbox, a shared task board they take work from, a company layer that grants and refuses capability, and a recorded, replayable trace of every run.

+

layer_gates[].status = passed · gates total

+
+
+

What changed for users recently

+

The newsroom went from parts to a production line: a researcher that re-checks whether its sources are still current, a writer that takes assignments through the formal routing path and emits articles whose every claim is linked to a source, and a fact-checker that reads the exact draft version rather than a summary of it.

+

changelog: L32-003 · L32-004 · L32-005 · L32-006 · L32-007 completed 2026-07-23/24

+
+
+

What the current stage will add

+

EXP → once the acceptance run for this stage passesThe newsroom's end-to-end run has passed its scripted check but not its human sign-off, so it is written here as an expectation rather than a fact. After it, the next stage is authority and governance: every action that reaches the outside world — publishing an article, for instance — has to clear a policy and permission gate first, which is what makes an autonomous newsroom safe to let out.

+

layer_gates[layer=32].status = scripted_passed (human acceptance not run) · L33-001…009 queued

+
+

Product · capability list unchanged since this generation

+
+ +

+ This list is derived from gates that reached passed; a gate that has only + passed its scripted run appears under an EXP chip naming the acceptance run that would + settle it. Nothing appears here on the strength of an unfinished gate. +

+
+
+ + +
+
+

Project · plan and progress

+

Where the plan has got to

+

Of tasks, are finished and are still open — and all but two of the open ones are simply waiting their turn.

+ +
+
+
+

What is queued behind this

+

Authority and governance comes next, then the stages that widen where material comes from and who is allowed to act on it. None of them has started; their tasks are written and waiting.

+
+ Show every open task, stage by stage +
    +
  • Authority and governance — policy, permission lattice, decision receipts
  • +
  • Dynamic source plane — widening where the newsroom draws material from
  • +
  • Later stages — written, queued, not yet opened
  • +
+
+

stories[].status = pending, grouped by layer · pending, deferred

+
+
+
+ + +
+
+

Project · ledger · facts that expire live here

+

What moved, and where reality drifted

+

places where the plan file and reality disagree — every one of them derived, none written from impression.

+ +
+

What moved

+

The newsroom pipeline landed across five tasks in two days, each merged through its own pull request with an independent evaluation before it counted as done. Two repair jobs opened against the same stage and are still open.

+

changelog[] 2026-07-23 → 2026-07-24 · stories[].status transitions

+
+ +
+

Where reality drifted

+
+

Work is marked done in stages that were never opened

+

Eight stages hold finished tasks while their acceptance run is still recorded as never started. Either the work outran its sign-off or the record was not kept up — both mean the control record no longer describes the project.

+

layer_gates[layer∈{2.5,3,5,7.5,13,27,28,29}].status = not_started with completed stories present

+
+
+

The plan and the work use different words for the same system

+

The plan file declares modules, but the work is actually filed against of them — names are in daily use and were never written down, while one declared module has never been touched. The control file's vocabulary and the team's vocabulary have come apart.

+

architecture.modules[].name vs stories[].module

+
+
+

The declared architecture can be checked against the code after all

+

Every task records which module it belongs to and which files it changed, so the link from concept to real code is measured rather than declared: of concepts resolve to something that exists. The plan file has no field for that link, which is why it looked unverifiable — the data was in the work record the whole time.

+

EXP → once modules[].paths lands in the schemaThe measured link becomes a declared one, and every stated dependency can be enforced as a rule with file-level evidence.

+

stories[].module × stories[].files_affected · modules declare a paths binding today

+
+

Two repairs keep failing against the same subsystem

+

Both open repair jobs carry a failure log, which is the shape of a specification and an implementation disagreeing rather than a flaky run. Finished tasks that once failed are not counted here; their logs are history.

+

stories[].failure_logs on open stories only

+
+
+

One acceptance state is not in the vocabulary

+

A single stage records a sign-off state that the system does not define, which means the control file's own wording has started to drift.

+

layer_gates[layer=20].status = "completed" (defined states: not_started → scripted_passed → passed)

+
+
+

The spending total says zero; the work record does not

+

The roll-up field reports nothing spent, but individual tasks carry a recorded dollar figure, together totalling . Nearly three quarters of it sits in one part of the system. The roll-up is not wired to the tasks underneath it — so the number to trust is the one derived here, not the declared one.

+

cost.total_usd = vs sum of stories[].cost_usd · by_module: agent, web, daemon, api, protocol

+
+
+ +

+ Every drift row is derived and cites its source — none is written from impression. + Unchipped = fact; EXP = an expectation, with the condition that would settle it. +

+
+
+ + +
+
+

Engineering · the system itself

+

What the system is made of

+

The system today is code units joined by dependencies — and the queued design introduces entirely new subsystems, every one of them planned inside something that already exists.

+ +
+
+
+

scan-workspace.mjs → rules R1–R10 → archify validate/deliver · concept binding from stories[].module × files_affected · code-verified · commit

+

The first view is what exists: real units, real dependencies, each labelled with how many concepts the work record says it carries. The second projects the queued design onto it — which units receive the new work, and which receive none. The third is the plan file's own account, which is written rather than verified; where it and the first two disagree, that disagreement is recorded in the ledger above.

+

Engineering · architecture unchanged since this generation

+
+ +
+

One part of the system is about to carry a great deal at once

+

The queued design places separate subsystems — authority, learning, event backbone, business adapters, incident handling, data governance and deliberation — inside a single existing unit, across files. Of the possible pairings between them, share no file at all. So they are not tangled: the plan has already divided this work cleanly, and given the division nothing to enforce it.

+

trigger: concept crowding · stories[status=open].module × files_affected · unit: do-agent

+ +
+
Leave it as one unit
+
+
Buys
No migration at all; the groups barely overlap already, so a directory convention may be enough.
+
Costs
The boundary cannot be enforced — nothing fails when someone crosses it.
+
Design
One folder per subsystem, plus an import rule that forbids reaching sideways.
+
Settled by
The first files that genuinely need shared state across two of these groups.
+
+
+ +
+
Split along the seams the plan already drew
+
+
Buys
Real runtime isolation: independent scaling, and one failing subsystem stops taking the others down.
+
Costs
These units talk over the network, and the authority check sits on the publishing path — so every outward action pays one extra hop.
+
Design
Follow the measured seams; the groups are already almost disjoint, so few files move twice.
+
Settled by
A latency budget for the authority check.
+
+
+ +
+
Extract only the cleanest one first
+
+
Buys
The highest-value separation for a single hop, and it can be done before the rest of the work starts.
+
Costs
The remaining groups stay unbounded; the question returns later, larger.
+
Design
Incident handling shares zero files with any of the other six — the cleanest cut available.
+
Settled by
Whether the other groups start sharing files as their work is dispatched.
+
+
+ +

GOAL → layer L33 onwardRanked here by seam cost alone, cheapest first: extract-one, then split, then leave-as-is. That criterion is deliberately narrow — rank by security isolation instead and the order reverses, because the authority subsystem is the one worth separating first regardless of price.

+
+ +
+

How the project moves, and the five stages of a task

+

These two diagrams are the only place this brief's vocabulary is defined. Solid lines are the normal path — the same five cells that sit beside every task row above. Dashed lines are exception markers. The step from failed back to pending is one only a person may take, which is why the top of this page has an ask at all.

+
+
+

Engineering · loop and states unchanged since this generation

+
+ +
+

How to check any of this

+

Every number on this page is bound to a field in a machine-derived facts file; none was typed by the agent that wrote the prose. The small type under each statement names the field it came from, so any claim here can be traced back to the plan file or to the code scan. An independent audit re-checks those bindings before the page is written.

+

The audit could not derive of its signals from this plan file because the fields they need are absent. They are recorded as unavailable rather than reported as clear.

+

+
+
+
+ + + + + + + + diff --git a/docs/human-alignment/example-looplia/facts.json b/docs/human-alignment/example-looplia/facts.json index 27c7916..ede54bf 100644 --- a/docs/human-alignment/example-looplia/facts.json +++ b/docs/human-alignment/example-looplia/facts.json @@ -11,8 +11,8 @@ "completed": 333, "deferred": 16, "failed": 2, - "ready": 1, - "pending": 44 + "ready": 2, + "pending": 43 }, "open_total": 47, "current_layer": 32, @@ -394,16 +394,39 @@ "layer_stories": 4 } }, + { + "kind": "control_plane_incoherence", + "layer": null, + "detail": "cost roll-up declares 0 while 34 stories sum to 735.15", + "path": "cost.total_usd vs stories[].cost_usd", + "level": "derived", + "counters": { + "priced_stories": 34 + } + }, + { + "kind": "control_plane_incoherence", + "layer": null, + "detail": "13 module names are used by stories but never declared, and 1 declared modules have never been worked", + "path": "architecture.modules[].name vs stories[].module", + "level": "derived", + "counters": { + "used_not_declared": 13, + "declared_not_used": 1 + } + }, { "kind": "declared_vs_actual", "layer": null, - "detail": "code has 21 workspace packages, the YAML declares 32 conceptual modules, 1 names in common; no architecture.modules[].paths binds them, so declared edges are not code-addressable", - "path": "architecture.modules[].paths", + "detail": "30 of 44 concept modules resolve to real code through the work record; 14 carry no resolvable path. The binding is measured, not declared — architecture.modules[].paths would record it, and 0 modules carry it today", + "path": "stories[].module × stories[].files_affected", "level": "code-verified", "counters": { - "code_packages": 21, + "code_units": 21, + "concepts_used": 44, + "concepts_code_bound": 30, "declared_modules": 32, - "name_overlap": 1 + "paths_declared": 0 } } ], @@ -4471,7 +4494,7 @@ { "layer": 41, "counts": { - "pending": 1 + "ready": 1 }, "total": 1, "gate_status": "not_started", @@ -4480,8 +4503,8 @@ { "id": "L41-001", "title": "Cloudflare-only autonomous newsroom dynamic exploration, source reading and information integration", - "status": "pending", - "stage": 1, + "status": "ready", + "stage": 2, "exception": null, "why": null } @@ -4490,7 +4513,7 @@ ], "changelog_recent": [ { - "id": "2026-07-22-dispatch-203", + "id": "2026-07-22-dispatch-204", "date": "2026-07-22", "kind": "dispatch", "author": "aep-dispatch", @@ -4498,7 +4521,7 @@ "since_baseline": false }, { - "id": "2026-07-23-reflection-204", + "id": "2026-07-23-reflection-205", "date": "2026-07-23", "kind": "reflection", "author": "aep-wrap", @@ -4506,7 +4529,7 @@ "since_baseline": false }, { - "id": "2026-07-23-dispatch-205", + "id": "2026-07-23-dispatch-206", "date": "2026-07-23", "kind": "dispatch", "author": "aep-dispatch", @@ -4514,7 +4537,7 @@ "since_baseline": false }, { - "id": "2026-07-23-dispatch-206", + "id": "2026-07-23-dispatch-207", "date": "2026-07-23", "kind": "dispatch", "author": "aep-dispatch", @@ -4522,7 +4545,7 @@ "since_baseline": false }, { - "id": "2026-07-23-reflection-207", + "id": "2026-07-23-reflection-208", "date": "2026-07-23", "kind": "reflection", "author": "aep-wrap", @@ -4530,7 +4553,7 @@ "since_baseline": false }, { - "id": "2026-07-23-reflection-208", + "id": "2026-07-23-reflection-209", "date": "2026-07-23", "kind": "reflection", "author": "aep-wrap", @@ -4538,7 +4561,7 @@ "since_baseline": false }, { - "id": "2026-07-23-dispatch-209", + "id": "2026-07-23-dispatch-210", "date": "2026-07-23", "kind": "dispatch", "author": "aep-dispatch", @@ -4546,7 +4569,7 @@ "since_baseline": false }, { - "id": "2026-07-23-reflection-210", + "id": "2026-07-23-reflection-211", "date": "2026-07-23", "kind": "reflection", "author": "aep-wrap", @@ -4554,7 +4577,7 @@ "since_baseline": false }, { - "id": "2026-07-23-dispatch-211", + "id": "2026-07-23-dispatch-212", "date": "2026-07-23", "kind": "dispatch", "author": "aep-dispatch", @@ -4562,7 +4585,7 @@ "since_baseline": false }, { - "id": "2026-07-24-reflection-212", + "id": "2026-07-24-reflection-213", "date": "2026-07-24", "kind": "reflection", "author": "aep-wrap", @@ -4570,7 +4593,7 @@ "since_baseline": false }, { - "id": "2026-07-24-dispatch-213", + "id": "2026-07-24-dispatch-214", "date": "2026-07-24", "kind": "dispatch", "author": "aep-dispatch", @@ -4578,7 +4601,7 @@ "since_baseline": false }, { - "id": "2026-07-24-reflection-214", + "id": "2026-07-24-reflection-215", "date": "2026-07-24", "kind": "reflection", "author": "aep-wrap", @@ -4797,14 +4820,43 @@ ], "cost": { "total_usd": 0, - "instrumented": false, - "by_layer_count": 0, - "by_story_count": 25, - "note": "cost plane declared but unwired" + "derived_total_usd": 735.15, + "priced_story_count": 34, + "story_total": 396, + "by_module": { + "web": 105.77, + "agent": 543.8, + "api": 14.37, + "daemon": 55.09, + "protocol": 9.76, + "auth": 6.36 + }, + "rollup_disagrees": true, + "instrumented": true }, "modules": { "declared_count": 32, "path_bound_count": 0, + "used_count": 44, + "code_bound_count": 30, + "used_not_declared": [ + "agent", + "agent-email", + "agent-memory-and-skills", + "agent-platform", + "agent-runtime", + "deployment-infrastructure", + "do-agent", + "docs", + "e2e", + "e2e-test", + "e2e-verification", + "infra", + "server" + ], + "declared_not_used": [ + "workload-identity-secrets-execution" + ], "names": [ "api", "auth", @@ -4840,6 +4892,638 @@ "business-system-adapters" ] }, + "structure": { + "now": { + "units": 21, + "edges": 75, + "commit": "65e359c6" + }, + "concepts": [ + { + "module": "agent", + "declared": false, + "responsibility": null, + "files": 68, + "units": [ + "@looplia/agent", + "@looplia/agent-e2e-test", + "@looplia/agent-runtime", + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/do-relay", + "@looplia/infra", + "@looplia/protocol", + "server", + "web" + ] + }, + { + "module": "agent-email", + "declared": false, + "responsibility": null, + "files": 13, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/infra" + ] + }, + { + "module": "agent-memory", + "declared": true, + "responsibility": "Single-agent durable memory and skill lifecycle: Workspace-backed identity, people memory, org context, agent notes, machine familiarity, thread summaries, skill recall, scheduled consolidation, MemoryManager orchestration, and curator safety. Layer 26 (memory-through-execution): the AUTONOMOUS execution loop (agent_run_step turns) also routes back into durable memory — closing the today-only-chat write-back gap — and the person store becomes RELATIONAL (owner / peer-agent / external-counterparty keyed by channel id, with task-relevant retrieval of the current counterparty, not only the primary person). Layer 28 (Hermes-grade durability, research-note/22): standing goals get goal-scoped working memory (/memory/goals/.md, a new goal-state taxonomy class — bounded replace-in-place, trigger-goal-scoped writes, task-relevant injection, archived on retirement); the 1500-token cap stops failing silently (in-turn usage header + dropped-source notice, over-cap targeted consolidation, distill circuit breaker, per-phase report retention); relationships get a lifecycle (hot/warm/cold _index.json sidecar, daily cold archival with transparent restore, an unresolved/ home for display-name-only parties merged on email discovery); and deprovisioning exports the agent Workspace as an OKF bundle before a two-phase teardown (memory becomes a company asset at exit).", + "files": 14, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "web" + ] + }, + { + "module": "agent-memory-and-skills", + "declared": false, + "responsibility": null, + "files": 23, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "web" + ] + }, + { + "module": "agent-platform", + "declared": false, + "responsibility": null, + "files": 8, + "units": [ + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "web" + ] + }, + { + "module": "agent-runtime", + "declared": false, + "responsibility": null, + "files": 3, + "units": [ + "@looplia/agent-runtime" + ] + }, + { + "module": "agent-self-improve", + "declared": true, + "responsibility": "The learning engine on top of agent-memory (Layer 8, Hermes background-review pattern): alarm-scheduled post-turn review runs, cadence counters, capacity-forced consolidation, review prompt pack, curator lifecycle states, learning-event surfacing, and per-agent review budgets. Layer 26 extends the review/skill-from-experience engine — today wired only to the /agui chat path — onto the EXECUTION loop (agent_run_step), and schedules the skill-curator lifecycle pass (which today never fires), so employees compound reusable skills from the work they DO. FIX-SKILL-REVIEW-001 (2026-07-07): the review tool gate must admit manage_skill — the L15-005 skill-write guard closed the generic write/edit route and the allowlist was never updated, leaving prod skill-authoring dead; the gate test must dispatch through the REAL guarded registry. Layer 28 (skill circulation): the skill-curator daily pass surfaces promotion proposals (usage+age thresholds); the COO supervision turn publishes proven skills to /company/wiki/skills//SKILL.md with provenance; hires seed from default pack UNION role-relevant library skills.", + "files": 9, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/agent-runtime", + "@looplia/do-agent" + ] + }, + { + "module": "api", + "declared": true, + "responsibility": "HTTP API gateway, WebSocket upgrade routing, daemon CRUD, session ticket generation, per-user session count guard", + "files": 34, + "units": [ + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/env", + "@looplia/infra", + "@looplia/protocol", + "server", + "web" + ] + }, + { + "module": "auth", + "declared": true, + "responsibility": "User signup/login (Better Auth), daemon API key generation/validation", + "files": 9, + "units": [ + "@looplia/auth", + "@looplia/db" + ] + }, + { + "module": "authority-kernel", + "declared": true, + "responsibility": "Normalize every material effect from chat, heartbeat, workflow, REST/MCP, UI and deterministic consumers into a typed ActionIntent; intersect company policy, Agent Operating Contract and scoped grant; enforce decision-right tiers and the CEO→COO/Managing Editor→employee command chain; emit machine-verifiable Decision Receipts.", + "files": 0, + "units": [] + }, + { + "module": "business-system-adapters", + "declared": true, + "responsibility": "Close the first professional vertical through CMS draft/version/preview/publish/update/hold/withdraw/correction, then separately gated newsletter/social distribution, reader analytics and correction intake. Later business systems reuse the stable query/propose/execute/reconcile adapter contract.", + "files": 0, + "units": [] + }, + { + "module": "cli", + "declared": true, + "responsibility": "User-facing CLI (looplia-run), OAuth login flow, interactive terminal session, daemon listing", + "files": 5, + "units": [] + }, + { + "module": "company-assurance-incident-ops", + "declared": true, + "responsibility": "Correlate company events, workflows, agent/model/tool calls, policy decisions, external effects, receipts and verifiers with OpenTelemetry; define company SLOs and Evaluation Registry promotion gates; manage first-class incidents with automatic containment, recovery and replay.", + "files": 0, + "units": [] + }, + { + "module": "company-context", + "declared": true, + "responsibility": "The virtual workspace mount layer (Layer 10): a dedicated CompanyContext DO running a Mirage-contract mount-table dispatcher that presents scoped external sources (Notion database/page subtree, Drive folder) as read-through paths under /company/* inside agent workspaces, with cache-on-read, per-mount ACL, and per-tenant OAuth. Layer 29 (living shared context, research-note/23): the wiki becomes the company operating library — briefing archive, goal dossiers, a daily-gated wiki curator pass and a per-mount sources digest; freshness markers reach every agent turn and the bounded projection remains protected. Meeting transcripts, raw paper full text and skill catalogs stay out of the always-on projection. route/receiveHandoff//org/handoff:* are permanently deprecated; Layer 36 deliberation uses typed durable artifacts instead of reviving them.", + "files": 20, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "@looplia/infra", + "server", + "web" + ] + }, + { + "module": "company-deliberation", + "declared": true, + "responsibility": "Run bounded independent-first deliberation: qualified participant selection, scoped evidence snapshots, independent positions, one targeted cross-exam, claim verification, synthesis with dissent, authority routing and follow-up tasks.", + "files": 0, + "units": [] + }, + { + "module": "company-event-workflow-backbone", + "declared": true, + "responsibility": "Provide the canonical CompanyEvent contract, per-company outbox/inbox dedup, Queue DLQ/replay operations, and Cloudflare Workflows bridge for durable multi-step business processes that wait for events, deadlines and approvals.", + "files": 0, + "units": [] + }, + { + "module": "company-formation-and-hiring", + "declared": true, + "responsibility": "Layer 13 company-agent formation and employee design boundary: turns a new account's company-agent interview into confirmed company facts, a canonical company brief, employee-agent blueprints, approval-backed hire_agent provisioning, and first-task receipts. Layer 27 (hire-for-goal): the blueprint carries an optional standingGoal {title, body, cadenceSeconds}; when present, provisioning mints an owned-goal anchor instead of the one-shot firstTask (rollback-safe, markHireConsumed last), and the hire approval shows the mission the employee will own.", + "files": 21, + "units": [ + "@looplia/api", + "@looplia/do-agent", + "web" + ] + }, + { + "module": "company-interaction-canvas", + "declared": true, + "responsibility": "Layer 13.5 human-machine interface for the company agent: company-agent-authored voice/text turns become durable declarative company UI surfaces, rendered from a trusted component catalog and bound to live company task/context/approval/blueprint/readiness projections.", + "files": 0, + "units": [] + }, + { + "module": "company-work-system", + "declared": true, + "responsibility": "The auto-company work ledger on the LoopliaCompany supervisor DO (Layer 9a): company_task / task_run / task_comment / approval tables, atomic checkout, heartbeat wake protocol, run liveness supervision, failure taxonomy, and the task board + approval card surfaces. Layer 26 (goal-ownership recursion): goal-ownership generalizes from the single COO north-star anchor to any goal-owner (owned-goal marker + generalized routeHeartbeatWake + parametrized goal-pursuit assembler); the single cron fans out schedule-wakes to each goal-owning EMPLOYEE (wiring the dead wakeForSchedule seam through the existing one-active-run coalescing) on a per-goal cadence (active/awaiting_reply/paused); the COO throttles to a planner (#needsSupervision); heartbeat + event unify into one trigger taxonomy (buildTurnTrigger). No new clock, no per-facet scheduleEvery; trust hierarchy (hire/mission COO-only) preserved. Layer 27 (topology closure, research-note/21): the cadence lifecycle gets its WRITE paths (set_goal_cadence own-goal-scoped verb, inbound-reply reactivation, per-goal cadence_seconds honored by the fan-out enumeration); owned goals get a completion lifecycle (employee proposes in_review -> a new #needsSupervision arm wakes the COO to verify -> done + cadence done, or feedback-return); the COO gains assign_standing_goal (kind:plan approval-gated, graduating to direct-mint via a per-company autonomy setting — goal-tree depth stays 2 by construction); employees escalate structurally (tagged @default comments counted by supervision); and the strategy surface lands (strategic-tier decision-log calls, cadenced CEO briefing email, approval-gated autonomous mission changes). Layer 29 adds a read-only scoped board verb (list_company_work: own subtree full, foreign goals summary-only) and the goal-portfolio operating-state projection v2 refreshed by EMPLOYEE owned-goal turns.", + "files": 33, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/infra", + "server", + "web" + ] + }, + { + "module": "connector-observer", + "declared": true, + "responsibility": "Layer 13 company-context freshness check (minimal slice): the company agent can ask which watched /company/wiki + scoped Notion sources changed since the brief was last confirmed, by reading the EXISTING mount warmer's fingerprints.", + "files": 3, + "units": [ + "@looplia/do-agent" + ] + }, + { + "module": "daemon", + "declared": true, + "responsibility": "PTY spawning (portable-pty), WebSocket client with auto-reconnect, daemon registration, API key storage in ~/.looplia/credentials", + "files": 32, + "units": [ + "@looplia/api", + "@looplia/db", + "@looplia/do-relay", + "@looplia/protocol", + "web" + ] + }, + { + "module": "data-governance-continuity", + "declared": true, + "responsibility": "Attach source/version/trust/classification/purpose/retention/jurisdiction metadata to company data, memories and derived artifacts; manage correction, quarantine, deletion and legal hold; create residency-aware company state and D1/DO/R2 recovery manifests with tested restore procedures.", + "files": 0, + "units": [] + }, + { + "module": "deployment-infrastructure", + "declared": false, + "responsibility": null, + "files": 0, + "units": [] + }, + { + "module": "do-agent", + "declared": false, + "responsibility": null, + "files": 43, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "server" + ] + }, + { + "module": "docs", + "declared": false, + "responsibility": null, + "files": 2, + "units": [] + }, + { + "module": "e2e", + "declared": false, + "responsibility": null, + "files": 4, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "web" + ] + }, + { + "module": "e2e-test", + "declared": false, + "responsibility": null, + "files": 23, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/do-agent" + ] + }, + { + "module": "e2e-verification", + "declared": false, + "responsibility": null, + "files": 12, + "units": [] + }, + { + "module": "email-api", + "declared": true, + "responsibility": "External agent surface. /v1/email/* REST and /mcp MCP server, mounted on apps/server. Validates Bearer aelk_… API keys, checks scope + rate limit + quota, RPCs into LoopliaAgent.", + "files": 12, + "units": [ + "@looplia/do-agent", + "@looplia/email-sdk-ts", + "@looplia/infra", + "server", + "web" + ] + }, + { + "module": "email-cli", + "declared": true, + "responsibility": "`looplia email` subcommand tree extending the existing apps/cli binary. Stateless commands, --json output, wraps email-api REST.", + "files": 12, + "units": [ + "server" + ] + }, + { + "module": "email-ingress", + "declared": true, + "responsibility": "MX-level inbound handler mounted on apps/server. Resolves → userId via a single D1 lookup; dispatches into LoopliaAgent.onEmail through routeAgentEmail.", + "files": 3, + "units": [ + "server" + ] + }, + { + "module": "email-outbound", + "declared": true, + "responsibility": "Adapter over Cloudflare Email Sending (public beta). Builds MIME with PostalMime, attaches HMAC-signed routing headers, calls env.EMAIL.send. Invoked only from LoopliaAgent.sendEmail.", + "files": 2, + "units": [ + "@looplia/email-protocol" + ] + }, + { + "module": "email-webhooks", + "declared": true, + "responsibility": "Outbound delivery of email events (email.received, email.delivered, email.bounced) to user-registered URLs. Signs payloads with HMAC-SHA256 + timestamp.", + "files": 3, + "units": [ + "@looplia/infra", + "server" + ] + }, + { + "module": "employee-capability-foundation", + "declared": true, + "responsibility": "Own the versioned professional employee product contract: archetypes, skill-bundle manifests and locks, EmployeeBlueprintV2 resolution, qualification suites, capability evidence, readiness status and routing eligibility.", + "files": 63, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/protocol" + ] + }, + { + "module": "fde-transformation-cockpit", + "declared": true, + "responsibility": "Layer 13 operator/FDE control surface: evaluates company readiness, maps first AI-employee opportunities, tracks rollout plan/progress/value evidence, and captures field learnings back into reusable product playbooks.", + "files": 0, + "units": [] + }, + { + "module": "infra", + "declared": false, + "responsibility": null, + "files": 3, + "units": [ + "@looplia/infra", + "server" + ] + }, + { + "module": "looplia-agent", + "declared": true, + "responsibility": "Per-user agent Durable Object (extends Cloudflare Agents SDK). Already orchestrates stories and runs Claude inference via CF AI Gateway. Layer 4 adds onEmail / sendEmail / listMessages / getMessage methods — LoopliaAgent is now also the canonical execution surface for inbound + outbound mail.", + "files": 10, + "units": [ + "@looplia/do-agent", + "server", + "web" + ] + }, + { + "module": "professional-execution-plane", + "declared": true, + "responsibility": "Accept capability-shaped professional execution intents through a compact facade, then resolve and run reproducible E0/E1/E2/E3 jobs through one broker/driver port; Workspace, packages and browser are additive governed capabilities rather than runtimes.", + "files": 77, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/do-agent", + "@looplia/env", + "@looplia/infra", + "@looplia/protocol" + ] + }, + { + "module": "professional-learning-loop", + "declared": true, + "responsibility": "Normalize qualification, routing and verified task outcomes into typed learning evidence; deterministically compute evidence sufficiency, workforce diagnosis and allowed interventions; let a version-locked COO planning skill rank/explain inside that boundary; turn approved retraining evidence into learned-overlay candidates, replay/canary/releases/rollback/requalification, or portfolio evidence into bounded team-composition proposals.", + "files": 0, + "units": [] + }, + { + "module": "protocol", + "declared": true, + "responsibility": "Wire format definitions (frame types, control messages, resize events)", + "files": 9, + "units": [ + "@looplia/do-relay", + "@looplia/email-protocol", + "@looplia/protocol" + ] + }, + { + "module": "relay", + "declared": true, + "responsibility": "WebSocket pair management (client + daemon), byte relay, heartbeat alarm, buffered audit log writes to D1", + "files": 5, + "units": [ + "@looplia/db", + "@looplia/do-relay", + "@looplia/e2e-test" + ] + }, + { + "module": "server", + "declared": false, + "responsibility": null, + "files": 0, + "units": [] + }, + { + "module": "voice", + "declared": true, + "responsibility": "Real-time voice pipeline (Layer 12): packages/voice exports VoiceGateway — a withVoice(Agent) DO (per userId:agentId:threadId) that terminates the browser voice WebSocket (PCM16 16kHz), validates a single-use voice ticket, streams ASR via Workers AI @cf/deepgram/flux, bridges final transcripts into the facet's voice-shaped turn entry point, sentence-streams TTS back (ONE provider, spike-chosen), enforces call guardrails (10-min cap, 60s idle hangup, unmuted-only ASR socket, per-user daily voice-minute quota), and emits per-stage latency metrics.", + "files": 11, + "units": [ + "@looplia/infra", + "@looplia/voice", + "server" + ] + }, + { + "module": "web", + "declared": true, + "responsibility": "Browser UI for signup, daemon listing, audit logs, guardrail config", + "files": 141, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "@looplia/protocol", + "@looplia/ui", + "server", + "web" + ] + } + ], + "concepts_total": 44, + "concepts_code_bound": 30, + "used_not_declared": [ + "agent", + "agent-email", + "agent-memory-and-skills", + "agent-platform", + "agent-runtime", + "deployment-infrastructure", + "do-agent", + "docs", + "e2e", + "e2e-test", + "e2e-verification", + "infra", + "server" + ], + "declared_not_used": [ + "workload-identity-secrets-execution" + ], + "next": [ + { + "module": "authority-kernel", + "declared": true, + "net_new": true, + "responsibility": "Normalize every material effect from chat, heartbeat, workflow, REST/MCP, UI and deterministic consumers into a typed ActionIntent; intersect company policy, Agent Operating Contract and scoped grant; enforce decision-right tiers and the CEO→COO/Managing Editor→employee command chain; emit machine-verifiable Decision Receipts.", + "files": 33, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/infra", + "@looplia/protocol", + "server", + "web" + ], + "homeless": false + }, + { + "module": "business-system-adapters", + "declared": true, + "net_new": true, + "responsibility": "Close the first professional vertical through CMS draft/version/preview/publish/update/hold/withdraw/correction, then separately gated newsletter/social distribution, reader analytics and correction intake. Later business systems reuse the stable query/propose/execute/reconcile adapter contract.", + "files": 19, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/api", + "@looplia/do-agent", + "@looplia/infra", + "@looplia/protocol" + ], + "homeless": false + }, + { + "module": "company-assurance-incident-ops", + "declared": true, + "net_new": true, + "responsibility": "Correlate company events, workflows, agent/model/tool calls, policy decisions, external effects, receipts and verifiers with OpenTelemetry; define company SLOs and Evaluation Registry promotion gates; manage first-class incidents with automatic containment, recovery and replay.", + "files": 15, + "units": [ + "@looplia/api", + "@looplia/do-agent", + "server" + ], + "homeless": false + }, + { + "module": "company-deliberation", + "declared": true, + "net_new": true, + "responsibility": "Run bounded independent-first deliberation: qualified participant selection, scoped evidence snapshots, independent positions, one targeted cross-exam, claim verification, synthesis with dissent, authority routing and follow-up tasks.", + "files": 12, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/do-agent", + "@looplia/protocol" + ], + "homeless": false + }, + { + "module": "company-event-workflow-backbone", + "declared": true, + "net_new": true, + "responsibility": "Provide the canonical CompanyEvent contract, per-company outbox/inbox dedup, Queue DLQ/replay operations, and Cloudflare Workflows bridge for durable multi-step business processes that wait for events, deadlines and approvals.", + "files": 19, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/do-agent", + "@looplia/env", + "@looplia/infra", + "@looplia/protocol", + "server" + ], + "homeless": false + }, + { + "module": "data-governance-continuity", + "declared": true, + "net_new": true, + "responsibility": "Attach source/version/trust/classification/purpose/retention/jurisdiction metadata to company data, memories and derived artifacts; manage correction, quarantine, deletion and legal hold; create residency-aware company state and D1/DO/R2 recovery manifests with tested restore procedures.", + "files": 14, + "units": [ + "@looplia/api", + "@looplia/db", + "@looplia/do-agent", + "@looplia/protocol" + ], + "homeless": false + }, + { + "module": "deployment-infrastructure", + "declared": false, + "net_new": true, + "responsibility": null, + "files": 6, + "units": [ + "@looplia/infra" + ], + "homeless": false + }, + { + "module": "professional-learning-loop", + "declared": true, + "net_new": true, + "responsibility": "Normalize qualification, routing and verified task outcomes into typed learning evidence; deterministically compute evidence sufficiency, workforce diagnosis and allowed interventions; let a version-locked COO planning skill rank/explain inside that boundary; turn approved retraining evidence into learned-overlay candidates, replay/canary/releases/rollback/requalification, or portfolio evidence into bounded team-composition proposals.", + "files": 27, + "units": [ + "@looplia/agent-e2e-test", + "@looplia/do-agent", + "@looplia/protocol" + ], + "homeless": false + } + ], + "next_net_new": [ + "authority-kernel", + "business-system-adapters", + "company-assurance-incident-ops", + "company-deliberation", + "company-event-workflow-backbone", + "data-governance-continuity", + "deployment-infrastructure", + "professional-learning-loop" + ], + "options": [ + { + "trigger": "concept_crowding", + "unit": "@looplia/do-agent", + "concepts": [ + "authority-kernel", + "business-system-adapters", + "company-assurance-incident-ops", + "company-deliberation", + "company-event-workflow-backbone", + "data-governance-continuity", + "professional-learning-loop" + ], + "concept_count": 7, + "files": 85, + "pairs": 21, + "disjoint_pairs": 17, + "disjoint_share": 0.81, + "cleanest_seam": { + "module": "company-assurance-incident-ops", + "shared_files": 0 + }, + "path": "stories[status=open].module × files_affected" + } + ] + }, "code_graph": { "nodes": 21, "edges": 75, diff --git a/docs/human-alignment/example-looplia/manifest.json b/docs/human-alignment/example-looplia/manifest.json index bc45406..a26f2ea 100644 --- a/docs/human-alignment/example-looplia/manifest.json +++ b/docs/human-alignment/example-looplia/manifest.json @@ -1,17 +1,17 @@ { "schema_version": 1, - "generated": "2026-07-25T0308Z", + "generated": "2026-07-25T0745Z", "commit": "65e359c6", - "output": "brief-2026-07-25T0308Z-65e359c6.html", - "facts_sha256": "028ac7ee9dea5970791e4020da8a20699b17e3712d1323bc440cb427244b271f", + "output": "brief-2026-07-25T0745Z-65e359c6.html", + "facts_sha256": "b1396d5c490de1b69f31a7db2c17bde4488f60a7b3e5300baf686be20c6b5882", "artifacts": [ "aep-loop", "architecture-declared", - "architecture-overview", - "architecture-packages", + "architecture-next", + "architecture-now", "story-states" ], "degraded": [], - "content_sha256": "05571cf8e5bbcee886089ad00280445c65e0c0c6d1f08d5f1a42371c22ab01f6", + "content_sha256": "b8b53ad21a10e58a5779bad82e6a73f133f894102b7c36ddd3288c02bd2fc51b", "history": [] } diff --git a/skills/human-alignment/assets/template.html b/skills/human-alignment/assets/template.html index 1e4a7aa..7a1ca57 100644 --- a/skills/human-alignment/assets/template.html +++ b/skills/human-alignment/assets/template.html @@ -340,6 +340,57 @@ margin: 0 0 4px; } + /* ── Design Option Sets (D8): suggestions carrying their material ──── */ + .options { + border: 1px solid var(--rule); + border-radius: 4px; + padding: 20px 22px; + margin: 24px 0; + } + .options > h4 { + font-family: var(--serif); + font-size: 19px; + font-weight: 600; + margin: 0 0 4px; + } + .option { + border-top: 1px solid var(--rule); + padding-top: 14px; + margin-top: 16px; + } + .option h5 { + font-family: var(--mono); + font-size: 12px; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--ink-2); + margin: 0 0 6px; + } + .option dl { + margin: 0; + display: grid; + grid-template-columns: 5.5rem 1fr; + gap: 2px 14px; + font-size: 15px; + } + .option dt { + font-family: var(--mono); + font-size: 11px; + text-transform: uppercase; + color: var(--ink-3); + padding-top: 4px; + } + .option dd { + margin: 0; + } + .criterion { + border-top: 1px solid var(--rule); + margin-top: 18px; + padding-top: 12px; + font-size: 14px; + color: var(--ink-2); + } + /* ── Disclosure: the folded queue ───────────────────────────────────── */ details { margin: 8px 0 18px; @@ -563,6 +614,8 @@

{{ENGINEERING_TITLE}}

Engineering · architecture unchanged since {{ARCHITECTURE_STAMP}}

+ {{OPTIONS_BLOCK}} +

{{LIFECYCLE_HEADING}}

{{LIFECYCLE_INTRO}}

@@ -717,8 +770,8 @@

{{PROVENANCE_HEADING}}

show(available[0]); } mountFrame("arch-host", [ - { key: "architecture-overview", label: "domain overview" }, - { key: "architecture-packages", label: "package deep-dive" }, + { key: "architecture-now", label: "what exists now" }, + { key: "architecture-next", label: "where the next design lands" }, { key: "architecture-declared", label: "declared narrative" }, ]); mountFrame("loop-host", [{ key: "aep-loop", label: "the loop" }]); diff --git a/skills/human-alignment/scripts/arch-rules.mjs b/skills/human-alignment/scripts/arch-rules.mjs index 1aae140..7e6de3c 100644 --- a/skills/human-alignment/scripts/arch-rules.mjs +++ b/skills/human-alignment/scripts/arch-rules.mjs @@ -47,7 +47,6 @@ const ROW_Y = 90; const ROW_STEP = 130; const unscoped = (name) => name.replace(/^@[^/]+\//, ""); -const stem = (name) => unscoped(name).split("-")[0]; // archify ids must match ^[a-zA-Z][a-zA-Z0-9_-]*$. Scoped package names // (@scope/pkg) would otherwise produce a leading dash and fail validation, so @@ -298,103 +297,85 @@ export function buildPackageTier(graph) { }; } -export function buildOverviewTier(graph) { - const kept = graph.nodes_detail.filter( - (n) => !RULES.R1_EXCLUDE.test(`${n.dir}/${unscoped(n.name)}`), - ); - const keptNames = new Set(kept.map((n) => n.name)); - - // R7 — domain = the deployment unit for apps, the name stem for packages. - const domainOf = new Map(); - for (const n of kept) { - const top = n.dir.split("/")[0]; - domainOf.set(n.name, top === "apps" ? unscoped(n.name) : stem(n.name)); +// R7 — concepts are BOUND to code units, never grouped by name. The binding is +// measured in derive.mjs from stories[].module x files_affected; this tier only +// renders it. There is no synthesized "domain" layer: inventing one from naming +// conventions produced 14 groups from 19 packages, 11 of them singletons, and +// discarded the project's own prose vocabulary (decision doc, revision 8). +export function buildNowTier(graph, structure) { + const base = buildPackageTier(graph); + const carried = new Map(); + for (const c of structure?.concepts ?? []) { + for (const u of c.units) { + if (!carried.has(u)) carried.set(u, []); + carried.get(u).push(c.module); + } } - const domains = [...new Set(domainOf.values())].sort(); - const membersOf = new Map( - domains.map((d) => [d, kept.filter((n) => domainOf.get(n.name) === d).map((n) => n.name)]), - ); - - // R8 — aggregate package edges to domain edges, dropping self-loops - let edges = []; - const seen = new Set(); - for (const e of graph.edges_detail) { - if (!keptNames.has(e.from) || !keptNames.has(e.to)) continue; - const a = domainOf.get(e.from); - const b = domainOf.get(e.to); - if (a === b) continue; - const key = `${a}|${b}`; - if (seen.has(key)) continue; - seen.add(key); - edges.push({ from: a, to: b }); + for (const comp of base.components) { + const unit = (graph.nodes_detail ?? []).find((n) => slug(n.name) === comp.id)?.name; + const concepts = (carried.get(unit) ?? []).sort(); + if (concepts.length) comp.sublabel = `${comp.sublabel} · ${concepts.length} concepts`; } + base.meta.title = `${graph.repo} · what exists now`; + base.meta.subtitle = `code-verified @ ${graph.commit} · ${base.components.length} units · concepts measured from the work record`; + base.meta.output = "architecture-now.html"; + base.cards = [ + base.cards[0], + { + dot: "emerald", + title: "Concepts carried, measured not declared", + items: [ + `${structure?.concepts_code_bound ?? 0} of ${structure?.concepts_total ?? 0} concept modules resolve to a real unit`, + `binding source: stories[].module x stories[].files_affected`, + `${(structure?.used_not_declared ?? []).length} concepts are used by work but never declared`, + ], + }, + ]; + return base; +} - // R2' — a domain everything depends on is chrome, not structure - const inDeg = new Map(domains.map((d) => [d, 0])); - for (const e of edges) inDeg.set(e.to, (inDeg.get(e.to) ?? 0) + 1); - const threshold = Math.ceil(domains.length * RULES.R2_UBIQUITY); - const folded = domains.filter((d) => (inDeg.get(d) ?? 0) >= threshold); - const foldedSet = new Set(folded); - const nodes = domains.filter((d) => !foldedSet.has(d)); - edges = edges.filter((e) => !foldedSet.has(e.from) && !foldedSet.has(e.to)); - - // R6 - edges = transitiveReduction(nodes, edges); - const pos = place(nodes, edges); - - const typeOfDomain = (d) => { - const members = membersOf.get(d) ?? []; - const types = members.map((m) => semanticType(m, kept.find((n) => n.name === m)?.dir ?? "")); - return types.find((t) => t !== RULES.R4_DEFAULT) ?? RULES.R4_DEFAULT; - }; - - return { - schema_version: 1, - diagram_type: "architecture", - meta: { - title: `${graph.repo} · domain overview`, - subtitle: `deterministic aggregation @ ${graph.commit} · ${graph.nodes} packages grouped into ${nodes.length} domains · code-verified`, - output: "architecture-overview.html", - quality_profile: "standard", - views: guidedViews(nodes, edges, (n) => n), +// Next — the queued design projected onto what exists. Units receiving net-new +// concepts are marked; this is the tier archify `compare` reads as "After". +export function buildNextTier(graph, structure) { + const base = buildPackageTier(graph); + const incoming = new Map(); + for (const c of structure?.next ?? []) { + for (const u of c.units) { + if (!incoming.has(u)) incoming.set(u, []); + incoming.get(u).push(c.module); + } + } + const byId = new Map((graph.nodes_detail ?? []).map((n) => [slug(n.name), n.name])); + const untouched = []; + for (const comp of base.components) { + const unit = byId.get(comp.id); + const arriving = (incoming.get(unit) ?? []).sort(); + if (arriving.length === 0) { + untouched.push(comp.id); + continue; + } + comp.sublabel = `${arriving.length} arriving`; + } + base.meta.title = `${graph.repo} · where the next design lands`; + base.meta.subtitle = `${(structure?.next ?? []).length} concept modules in queued work · ${(structure?.next_net_new ?? []).length} of them net-new · projected from open stories`; + base.meta.output = "architecture-next.html"; + base.cards = [ + { + dot: "amber", + title: "Net-new concepts the queued design introduces", + items: (structure?.next_net_new ?? []).slice(0, 6).map((m) => m), }, - components: nodes - .map((d) => ({ - id: slug(d), - type: typeOfDomain(d), - label: d, - sublabel: `${(membersOf.get(d) ?? []).length} package${(membersOf.get(d) ?? []).length === 1 ? "" : "s"}`, - pos: pos.get(d), - size: sizeFor(d), - })) - .sort((a, b) => a.id.localeCompare(b.id)), - boundaries: [], - connections: edges - .map((e) => ({ from: slug(e.from), to: slug(e.to) })) - .sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to)), - cards: [ - { - dot: "cyan", - title: "How domains were formed (rule R7, auditable)", - items: [ - "apps/* — each deployment unit is its own domain", - "packages/* — grouped by the first token of the package name", - folded.length - ? `R2' folded (depended on by everyone): ${folded.join(" · ")}` - : "R2' folded nothing", - ], - }, - { - dot: "emerald", - title: "Scan receipt", - items: [ - `commit ${graph.commit} · ${graph.nodes} packages, ${graph.edges} edges`, - `→ ${nodes.length} domains, ${edges.length} edges after R7/R8/R2'/R6`, - `tool: ${graph.tool}`, - ], - }, - ], - }; + { + dot: "cyan", + title: "How this projection was made", + items: [ + "open stories -> stories[].module -> stories[].files_affected -> code unit", + `${untouched.length} existing units receive no queued work`, + "no new code units are planned; every concept lands in something that exists", + ], + }, + ]; + return base; } export function buildDeclaredTier(ctx, graph) { @@ -471,9 +452,14 @@ if (process.argv[1] && process.argv[1].endsWith("arch-rules.mjs")) { const graph = JSON.parse(readFileSync(graphPath, "utf8")); const ctx = contextPath && existsSync(contextPath) ? await loadYaml(contextPath) : null; + const factsPath = arg("facts"); + const structure = + factsPath && existsSync(factsPath) + ? (JSON.parse(readFileSync(factsPath, "utf8")).structure ?? null) + : null; const tiers = { - "architecture-overview": buildOverviewTier(graph), - "architecture-packages": buildPackageTier(graph), + "architecture-now": buildNowTier(graph, structure), + "architecture-next": buildNextTier(graph, structure), "architecture-declared": buildDeclaredTier(ctx, graph), }; for (const [name, ir] of Object.entries(tiers)) { diff --git a/skills/human-alignment/scripts/assemble.mjs b/skills/human-alignment/scripts/assemble.mjs index f299261..c24a542 100644 --- a/skills/human-alignment/scripts/assemble.mjs +++ b/skills/human-alignment/scripts/assemble.mjs @@ -21,8 +21,8 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync import { basename, join, resolve } from "node:path"; const ARTIFACT_KEYS = [ - "architecture-overview", - "architecture-packages", + "architecture-now", + "architecture-next", "architecture-declared", "aep-loop", "story-states", diff --git a/skills/human-alignment/scripts/derive.mjs b/skills/human-alignment/scripts/derive.mjs index e385d33..8adb5df 100644 --- a/skills/human-alignment/scripts/derive.mjs +++ b/skills/human-alignment/scripts/derive.mjs @@ -364,6 +364,189 @@ export function deriveDriftFacts(ctx) { return facts; } +// ─── Structure: Now · Concepts · Next · Options (D3/D8) ──────────────────── +// The Engineering band's plane. Every value here is measured from the work +// record — `stories[].module` says which concept a piece of work belongs to, +// `stories[].files_affected` says where it landed. The concept-to-code binding +// is therefore observed, never declared and never guessed. + +const OPEN_WORK = new Set(["pending", "ready", "in_progress"]); + +// Fixed thresholds (D8). Configurable thresholds are knobs nobody turns. +export const OPTION_TRIGGERS = { + CROWDING_MIN_CONCEPTS: 4, + CROWDING_MIN_FILES: 30, + CROWDING_MIN_DISJOINT: 0.5, +}; + +const resolverFor = (codeGraph) => { + const dirs = (codeGraph?.nodes_detail ?? []) + .map((n) => [n.dir, n.name]) + .sort((a, b) => b[0].length - a[0].length); + return (p) => dirs.find(([dir]) => String(p).startsWith(dir + "/"))?.[1] ?? null; +}; + +export function deriveStructure(ctx, codeGraph) { + if (!codeGraph) return null; + const toUnit = resolverFor(codeGraph); + const stories = ctx.stories ?? []; + const declared = new Set((ctx.architecture?.modules ?? []).map((m) => String(m.name))); + const responsibility = new Map( + (ctx.architecture?.modules ?? []).map((m) => [String(m.name), m.responsibility ?? null]), + ); + + // Concept → files, split by whether the work is done or still queued. + const filesOf = (pool) => { + const out = new Map(); + for (const s of pool) { + const mod = s.module == null ? null : String(s.module); + if (!mod) continue; + if (!out.has(mod)) out.set(mod, new Set()); + for (const p of s.files_affected ?? []) out.get(mod).add(String(p)); + } + return out; + }; + const doneFiles = filesOf(stories.filter((s) => s.status === "completed")); + const nextFiles = filesOf(stories.filter((s) => OPEN_WORK.has(s.status))); + const used = new Set( + stories.map((s) => (s.module == null ? null : String(s.module))).filter(Boolean), + ); + + // Concepts: the vocabulary, bound to the code units that actually carry it. + const concepts = [...used].sort().map((m) => { + const files = doneFiles.get(m) ?? new Set(); + const units = [...new Set([...files].map(toUnit).filter(Boolean))].sort(); + return { + module: m, + declared: declared.has(m), + responsibility: isProse(responsibility.get(m)) ? String(responsibility.get(m)) : null, + files: files.size, + units, + }; + }); + + // Next: the queued design projected onto what exists. + const nextConcepts = [...nextFiles.keys()].sort().map((m) => { + const files = nextFiles.get(m); + const units = [...new Set([...files].map(toUnit).filter(Boolean))].sort(); + return { + module: m, + declared: declared.has(m), + net_new: !doneFiles.has(m), + responsibility: isProse(responsibility.get(m)) ? String(responsibility.get(m)) : null, + files: files.size, + units, + homeless: units.length === 0, + }; + }); + + // Concept load per code unit, restricted to the Next projection (D8 scope: + // running these detectors over history is measured noise, not signal). + const perUnit = new Map(); + for (const m of nextFiles.keys()) { + for (const p of nextFiles.get(m)) { + const unit = toUnit(p); + if (!unit) continue; + if (!perUnit.has(unit)) perUnit.set(unit, new Map()); + if (!perUnit.get(unit).has(m)) perUnit.get(unit).set(m, new Set()); + perUnit.get(unit).get(m).add(p); + } + } + + const options = []; + for (const [unit, byModule] of [...perUnit].sort()) { + const mods = [...byModule.keys()].sort(); + const mass = new Set([...byModule.values()].flatMap((s) => [...s])).size; + if (mods.length < OPTION_TRIGGERS.CROWDING_MIN_CONCEPTS) continue; + if (mass < OPTION_TRIGGERS.CROWDING_MIN_FILES) continue; + let pairs = 0; + let disjoint = 0; + const seams = []; + for (let i = 0; i < mods.length; i++) { + for (let j = i + 1; j < mods.length; j++) { + pairs++; + const shared = [...byModule.get(mods[i])].filter((p) => + byModule.get(mods[j]).has(p), + ).length; + if (shared === 0) disjoint++; + seams.push({ a: mods[i], b: mods[j], shared }); + } + } + const share = pairs === 0 ? 1 : disjoint / pairs; + if (share < OPTION_TRIGGERS.CROWDING_MIN_DISJOINT) continue; + // The cleanest first cut: the concept sharing fewest files with the rest. + const sharedTotal = new Map(mods.map((m) => [m, 0])); + for (const s of seams) { + sharedTotal.set(s.a, sharedTotal.get(s.a) + s.shared); + sharedTotal.set(s.b, sharedTotal.get(s.b) + s.shared); + } + const cleanest = [...sharedTotal].sort((a, b) => a[1] - b[1] || a[0].localeCompare(b[0]))[0]; + options.push({ + trigger: "concept_crowding", + unit, + concepts: mods, + concept_count: mods.length, + files: mass, + pairs, + disjoint_pairs: disjoint, + disjoint_share: Number(share.toFixed(2)), + cleanest_seam: { module: cleanest[0], shared_files: cleanest[1] }, + path: "stories[status=open].module × files_affected", + }); + } + for (const c of nextConcepts.filter((c) => c.homeless)) { + options.push({ + trigger: "homeless_concept", + unit: null, + concepts: [c.module], + concept_count: 1, + files: c.files, + pairs: 0, + disjoint_pairs: 0, + disjoint_share: 1, + cleanest_seam: null, + path: `stories[module=${c.module}].files_affected`, + }); + } + + const codeBound = concepts.filter((c) => c.units.length > 0).length; + return { + now: { units: codeGraph.nodes, edges: codeGraph.edges, commit: codeGraph.commit }, + concepts, + concepts_total: concepts.length, + concepts_code_bound: codeBound, + used_not_declared: [...used].filter((m) => !declared.has(m)).sort(), + declared_not_used: [...declared].filter((m) => !used.has(m)).sort(), + next: nextConcepts, + next_net_new: nextConcepts.filter((c) => c.net_new).map((c) => c.module), + options, + }; +} + +// ─── Cost: roll up from the work record, not the roll-up field ───────────── +export function deriveCost(ctx) { + const stories = ctx.stories ?? []; + const priced = stories.filter((s) => typeof s.cost_usd === "number" && s.cost_usd > 0); + const derivedTotal = priced.reduce((sum, s) => sum + s.cost_usd, 0); + const byModule = {}; + for (const s of priced) { + const m = s.module == null ? "unattributed" : String(s.module); + byModule[m] = Number(((byModule[m] ?? 0) + s.cost_usd).toFixed(2)); + } + const declaredTotal = num(ctx.cost?.total_usd); + return { + total_usd: declaredTotal, + derived_total_usd: Number(derivedTotal.toFixed(2)), + priced_story_count: priced.length, + story_total: stories.length, + by_module: byModule, + // A zeroed roll-up beside a non-zero story sum is a statement about the + // roll-up, not about the data — and their disagreement is itself drift. + rollup_disagrees: declaredTotal !== null && Math.abs(declaredTotal - derivedTotal) > 0.01, + instrumented: derivedTotal > 0, + }; +} + // ─── Main derivation ─────────────────────────────────────────────────────── export async function derive({ contextPath, manifestPath, repoRoot, codeGraph = null }) { const ctx = await loadYaml(contextPath); @@ -496,10 +679,8 @@ export async function derive({ contextPath, manifestPath, repoRoot, codeGraph = source: `layer_gates[layer=${g.layer}]`, })); - const cost = ctx.cost ?? {}; - const byStory = cost.by_story ?? {}; - const byLayerCost = cost.by_layer ?? {}; - const totalUsd = num(cost.total_usd); + const cost = deriveCost(ctx); + const structure = deriveStructure(ctx, codeGraph); const facts = { schema_version: 1, generated_from: "product-context.yaml", @@ -525,27 +706,50 @@ export async function derive({ contextPath, manifestPath, repoRoot, codeGraph = layers, changelog_recent: changelogRecent, capabilities, - cost: { - total_usd: totalUsd, - instrumented: totalUsd !== null && totalUsd > 0, - by_layer_count: Object.keys(byLayerCost).length, - by_story_count: Object.keys(byStory).length, - note: - totalUsd === 0 && Object.keys(byStory).length > 0 - ? "cost plane declared but unwired" - : null, - }, + cost, modules: { declared_count: (ctx.architecture?.modules ?? []).length, path_bound_count: (ctx.architecture?.modules ?? []).filter( (m) => Array.isArray(m.paths) && m.paths.length > 0, ).length, + used_count: structure ? structure.concepts_total : null, + code_bound_count: structure ? structure.concepts_code_bound : null, + used_not_declared: structure ? structure.used_not_declared : [], + declared_not_used: structure ? structure.declared_not_used : [], names: (ctx.architecture?.modules ?? []).map((m) => String(m.name)), }, + structure, code_graph: codeGraph, delta, }; + // Cost drift: a zeroed roll-up beside a non-zero story sum. + if (cost.rollup_disagrees) { + facts.drift_facts.push({ + kind: "control_plane_incoherence", + layer: null, + detail: `cost roll-up declares ${cost.total_usd} while ${cost.priced_story_count} stories sum to ${cost.derived_total_usd}`, + path: "cost.total_usd vs stories[].cost_usd", + level: "derived", + counters: { priced_stories: cost.priced_story_count }, + }); + } + + // Module vocabulary drift: the control plane and the work using different words. + if (structure && (structure.used_not_declared.length || structure.declared_not_used.length)) { + facts.drift_facts.push({ + kind: "control_plane_incoherence", + layer: null, + detail: `${structure.used_not_declared.length} module names are used by stories but never declared, and ${structure.declared_not_used.length} declared modules have never been worked`, + path: "architecture.modules[].name vs stories[].module", + level: "derived", + counters: { + used_not_declared: structure.used_not_declared.length, + declared_not_used: structure.declared_not_used.length, + }, + }); + } + // 5 · declared vs actual — only when a scan is present if (codeGraph) { const declared = new Set(facts.modules.names); @@ -565,17 +769,23 @@ export async function derive({ contextPath, manifestPath, repoRoot, codeGraph = commit: codeGraph.commit, }).filter(([, v]) => v !== undefined), ); - if (facts.modules.path_bound_count === 0) { + // Drift 5 restated (revision 8). The declared architecture IS + // code-addressable — through the work record. Report what the measurement + // found, not the absence of a schema field. + if (structure) { + const unbound = structure.concepts.filter((c) => c.units.length === 0).length; facts.drift_facts.push({ kind: "declared_vs_actual", layer: null, - detail: `code has ${codeGraph.nodes} workspace packages, the YAML declares ${facts.modules.declared_count} conceptual modules, ${overlap} names in common; no architecture.modules[].paths binds them, so declared edges are not code-addressable`, - path: "architecture.modules[].paths", + detail: `${structure.concepts_code_bound} of ${structure.concepts_total} concept modules resolve to real code through the work record; ${unbound} carry no resolvable path. The binding is measured, not declared — architecture.modules[].paths would record it, and ${facts.modules.path_bound_count} modules carry it today`, + path: "stories[].module × stories[].files_affected", level: "code-verified", counters: { - code_packages: codeGraph.nodes, + code_units: codeGraph.nodes, + concepts_used: structure.concepts_total, + concepts_code_bound: structure.concepts_code_bound, declared_modules: facts.modules.declared_count, - name_overlap: overlap, + paths_declared: facts.modules.path_bound_count, }, }); } diff --git a/skills/human-alignment/scripts/facts.schema.json b/skills/human-alignment/scripts/facts.schema.json index e219f01..9324d62 100644 --- a/skills/human-alignment/scripts/facts.schema.json +++ b/skills/human-alignment/scripts/facts.schema.json @@ -23,24 +23,47 @@ "modules" ], "properties": { - "schema_version": { "const": 1 }, - "generated_from": { "type": "string" }, - "commit": { "type": "string", "description": "short git SHA of HEAD at derivation" }, + "schema_version": { + "const": 1 + }, + "generated_from": { + "type": "string" + }, + "commit": { + "type": "string", + "description": "short git SHA of HEAD at derivation" + }, "baseline_commit": { "type": ["string", "null"], "description": "commit of the previous generation, or null on first run" }, - "project": { "type": "string" }, - "version": { "type": ["string", "null"] }, - "updated_at": { "type": ["string", "null"] }, - "story_total": { "type": "integer", "minimum": 0 }, + "project": { + "type": "string" + }, + "version": { + "type": ["string", "null"] + }, + "updated_at": { + "type": ["string", "null"] + }, + "story_total": { + "type": "integer", + "minimum": 0 + }, "by_status": { "type": "object", - "additionalProperties": { "type": "integer", "minimum": 0 } + "additionalProperties": { + "type": "integer", + "minimum": 0 + } + }, + "open_total": { + "type": "integer", + "minimum": 0 + }, + "current_layer": { + "type": ["number", "null"] }, - "open_total": { "type": "integer", "minimum": 0 }, - "current_layer": { "type": ["number", "null"] }, - "attention_set": { "type": "array", "items": { @@ -48,7 +71,11 @@ "additionalProperties": false, "required": ["rank", "kind", "verb", "id", "title", "path"], "properties": { - "rank": { "type": "integer", "minimum": 1, "maximum": 6 }, + "rank": { + "type": "integer", + "minimum": 1, + "maximum": 6 + }, "kind": { "enum": [ "failed", @@ -59,11 +86,21 @@ "open_question" ] }, - "verb": { "type": "string" }, - "id": { "type": "string" }, - "title": { "type": "string" }, - "layer": { "type": ["number", "null"] }, - "path": { "type": "string" }, + "verb": { + "type": "string" + }, + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "layer": { + "type": ["number", "null"] + }, + "path": { + "type": "string" + }, "why": { "type": ["string", "null"], "description": "prose-typed only; numeric sources are dropped, never rendered" @@ -72,9 +109,15 @@ } }, "one_ask": { - "oneOf": [{ "type": "null" }, { "$ref": "#/properties/attention_set/items" }] + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/properties/attention_set/items" + } + ] }, - "schema_absent": { "type": "array", "description": "One record per predicate skipped because its fields are absent. An empty attention_set is only trustworthy when this array is also empty.", @@ -83,13 +126,18 @@ "additionalProperties": false, "required": ["predicate", "path", "reason"], "properties": { - "predicate": { "type": "string" }, - "path": { "type": "string" }, - "reason": { "type": "string" } + "predicate": { + "type": "string" + }, + "path": { + "type": "string" + }, + "reason": { + "type": "string" + } } } }, - "drift_facts": { "type": "array", "items": { @@ -106,25 +154,42 @@ "declared_vs_actual" ] }, - "layer": { "type": ["number", "null"] }, - "detail": { "type": "string" }, - "path": { "type": "string" }, - "level": { "enum": ["derived", "code-verified", "unverified"] }, + "layer": { + "type": ["number", "null"] + }, + "detail": { + "type": "string" + }, + "path": { + "type": "string" + }, + "level": { + "enum": ["derived", "code-verified", "unverified"] + }, "counters": { "type": "object", - "additionalProperties": { "type": "integer" } + "additionalProperties": { + "type": "integer" + } } } } }, - "gates": { "type": "object", "additionalProperties": false, "required": ["total", "by_status", "detail"], "properties": { - "total": { "type": "integer", "minimum": 0 }, - "by_status": { "type": "object", "additionalProperties": { "type": "integer" } }, + "total": { + "type": "integer", + "minimum": 0 + }, + "by_status": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, "vocabulary_violations": { "type": "array", "items": { @@ -132,9 +197,15 @@ "additionalProperties": false, "required": ["layer", "status", "path"], "properties": { - "layer": { "type": "number" }, - "status": { "type": "string" }, - "path": { "type": "string" } + "layer": { + "type": "number" + }, + "status": { + "type": "string" + }, + "path": { + "type": "string" + } } } }, @@ -145,11 +216,21 @@ "additionalProperties": false, "required": ["layer", "status"], "properties": { - "layer": { "type": "number" }, - "status": { "type": "string" }, - "criteria_total": { "type": ["integer", "null"] }, - "criteria_covered": { "type": ["integer", "null"] }, - "completed_at": { "type": ["string", "null"] }, + "layer": { + "type": "number" + }, + "status": { + "type": "string" + }, + "criteria_total": { + "type": ["integer", "null"] + }, + "criteria_covered": { + "type": ["integer", "null"] + }, + "completed_at": { + "type": ["string", "null"] + }, "shippable": { "type": "boolean", "description": "true only for status == passed; scripted_passed is EXP, never fact" @@ -159,7 +240,6 @@ } } }, - "layers": { "type": "array", "items": { @@ -167,11 +247,24 @@ "additionalProperties": false, "required": ["layer", "counts", "gate_status"], "properties": { - "layer": { "type": "number" }, - "counts": { "type": "object", "additionalProperties": { "type": "integer" } }, - "total": { "type": "integer" }, - "gate_status": { "type": ["string", "null"] }, - "is_current": { "type": "boolean" }, + "layer": { + "type": "number" + }, + "counts": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "total": { + "type": "integer" + }, + "gate_status": { + "type": ["string", "null"] + }, + "is_current": { + "type": "boolean" + }, "stories": { "type": "array", "items": { @@ -179,19 +272,32 @@ "additionalProperties": false, "required": ["id", "title", "status", "stage"], "properties": { - "id": { "type": "string" }, - "title": { "type": "string" }, - "status": { "type": "string" }, - "stage": { "type": "integer", "minimum": 0, "maximum": 5 }, - "exception": { "type": ["string", "null"] }, - "why": { "type": ["string", "null"] } + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "status": { + "type": "string" + }, + "stage": { + "type": "integer", + "minimum": 0, + "maximum": 5 + }, + "exception": { + "type": ["string", "null"] + }, + "why": { + "type": ["string", "null"] + } } } } } } }, - "changelog_recent": { "type": "array", "items": { @@ -203,15 +309,24 @@ "type": "string", "description": "stable binding key: date + kind + index; translations bind by id, never by list position" }, - "date": { "type": "string" }, - "kind": { "type": ["string", "null"] }, - "author": { "type": ["string", "null"] }, - "summary": { "type": "string" }, - "since_baseline": { "type": "boolean" } + "date": { + "type": "string" + }, + "kind": { + "type": ["string", "null"] + }, + "author": { + "type": ["string", "null"] + }, + "summary": { + "type": "string" + }, + "since_baseline": { + "type": "boolean" + } } } }, - "capabilities": { "type": "array", "description": "Band 2 inputs. passed gates yield facts; scripted_passed gates are EXP-chipped and never unchipped.", @@ -220,78 +335,157 @@ "additionalProperties": false, "required": ["layer", "gate_status", "tense", "source"], "properties": { - "layer": { "type": "number" }, - "gate_status": { "enum": ["passed", "scripted_passed"] }, - "tense": { "enum": ["IS", "EXP"] }, - "settles_on": { "type": ["string", "null"] }, - "definition": { "type": ["string", "null"] }, - "completed_at": { "type": ["string", "null"] }, - "source": { "type": "string" } + "layer": { + "type": "number" + }, + "gate_status": { + "enum": ["passed", "scripted_passed"] + }, + "tense": { + "enum": ["IS", "EXP"] + }, + "settles_on": { + "type": ["string", "null"] + }, + "definition": { + "type": ["string", "null"] + }, + "completed_at": { + "type": ["string", "null"] + }, + "source": { + "type": "string" + } } } }, - "cost": { "type": "object", "additionalProperties": false, - "required": ["total_usd", "instrumented"], + "required": ["derived_total_usd", "priced_story_count", "instrumented"], "properties": { - "total_usd": { "type": ["number", "null"] }, - "instrumented": { - "type": "boolean", - "description": "false when the cost plane is declared but unwired" + "total_usd": { + "type": ["number", "null"], + "description": "the declared roll-up; a zero here is a statement about the roll-up, not the data" + }, + "derived_total_usd": { + "type": "number", + "description": "summed from stories[].cost_usd \u2014 the work record" + }, + "priced_story_count": { + "type": "integer", + "minimum": 0 + }, + "story_total": { + "type": "integer", + "minimum": 0 + }, + "by_module": { + "type": "object", + "additionalProperties": { + "type": "number" + } }, - "by_layer_count": { "type": "integer" }, - "by_story_count": { "type": "integer" }, - "note": { "type": ["string", "null"] } + "rollup_disagrees": { + "type": "boolean" + }, + "instrumented": { + "type": "boolean" + } } }, - "modules": { "type": "object", "additionalProperties": false, "required": ["declared_count", "path_bound_count"], "properties": { - "declared_count": { "type": "integer" }, + "declared_count": { + "type": "integer" + }, "path_bound_count": { "type": "integer", "description": "modules carrying architecture.modules[].paths" }, - "names": { "type": "array", "items": { "type": "string" } } + "names": { + "type": "array", + "items": { + "type": "string" + } + }, + "used_count": { + "type": ["integer", "null"], + "description": "distinct modules stories are filed against" + }, + "code_bound_count": { + "type": ["integer", "null"], + "description": "concepts resolving to at least one code unit" + }, + "used_not_declared": { + "type": "array", + "items": { + "type": "string" + } + }, + "declared_not_used": { + "type": "array", + "items": { + "type": "string" + } + } } }, - "code_graph": { "oneOf": [ - { "type": "null" }, + { + "type": "null" + }, { "type": "object", "additionalProperties": false, "required": ["nodes", "edges", "tool"], "properties": { - "nodes": { "type": "integer" }, - "edges": { "type": "integer" }, - "apps": { "type": "integer" }, - "packages": { "type": "integer" }, - "domains": { "type": "integer" }, - "domain_edges": { "type": "integer" }, + "nodes": { + "type": "integer" + }, + "edges": { + "type": "integer" + }, + "apps": { + "type": "integer" + }, + "packages": { + "type": "integer" + }, + "domains": { + "type": "integer" + }, + "domain_edges": { + "type": "integer" + }, "name_overlap": { "type": "integer", "description": "declared module names that match a real package name" }, - "tool": { "type": "string" }, - "commit": { "type": "string" } + "tool": { + "type": "string" + }, + "commit": { + "type": "string" + } } } ] }, - "delta": { "type": "object", "additionalProperties": false, "properties": { - "first_run": { "type": "boolean" }, - "commits_since_baseline": { "type": ["integer", "null"] }, + "first_run": { + "type": "boolean" + }, + "commits_since_baseline": { + "type": ["integer", "null"] + }, "status_changes": { "type": "array", "items": { @@ -299,14 +493,206 @@ "additionalProperties": false, "required": ["id", "from", "to"], "properties": { - "id": { "type": "string" }, - "from": { "type": ["string", "null"] }, - "to": { "type": "string" } + "id": { + "type": "string" + }, + "from": { + "type": ["string", "null"] + }, + "to": { + "type": "string" + } } } }, - "changelog_new": { "type": "integer" } + "changelog_new": { + "type": "integer" + } } + }, + "structure": { + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": false, + "required": ["now", "concepts", "next", "options"], + "description": "The Engineering plane: Now (real structure) \u00b7 Concepts (vocabulary measured onto it) \u00b7 Next (queued design projected) \u00b7 Options (D8 triggers).", + "properties": { + "now": { + "type": "object", + "additionalProperties": false, + "required": ["units", "edges"], + "properties": { + "units": { + "type": "integer" + }, + "edges": { + "type": "integer" + }, + "commit": { + "type": "string" + } + } + }, + "concepts": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["module", "files", "units"], + "properties": { + "module": { + "type": "string" + }, + "declared": { + "type": "boolean" + }, + "net_new": { + "type": "boolean" + }, + "responsibility": { + "type": ["string", "null"] + }, + "files": { + "type": "integer", + "minimum": 0 + }, + "units": { + "type": "array", + "items": { + "type": "string" + } + }, + "homeless": { + "type": "boolean" + } + } + } + }, + "concepts_total": { + "type": "integer" + }, + "concepts_code_bound": { + "type": "integer" + }, + "used_not_declared": { + "type": "array", + "items": { + "type": "string" + } + }, + "declared_not_used": { + "type": "array", + "items": { + "type": "string" + } + }, + "next": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["module", "files", "units"], + "properties": { + "module": { + "type": "string" + }, + "declared": { + "type": "boolean" + }, + "net_new": { + "type": "boolean" + }, + "responsibility": { + "type": ["string", "null"] + }, + "files": { + "type": "integer", + "minimum": 0 + }, + "units": { + "type": "array", + "items": { + "type": "string" + } + }, + "homeless": { + "type": "boolean" + } + } + } + }, + "next_net_new": { + "type": "array", + "items": { + "type": "string" + } + }, + "options": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["trigger", "concepts", "path"], + "properties": { + "trigger": { + "enum": ["concept_crowding", "homeless_concept"] + }, + "unit": { + "type": ["string", "null"] + }, + "concepts": { + "type": "array", + "items": { + "type": "string" + } + }, + "concept_count": { + "type": "integer" + }, + "files": { + "type": "integer" + }, + "pairs": { + "type": "integer" + }, + "disjoint_pairs": { + "type": "integer" + }, + "disjoint_share": { + "type": "number" + }, + "cleanest_seam": { + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "module": { + "type": "string" + }, + "shared_files": { + "type": "integer" + } + } + } + ] + }, + "path": { + "type": "string" + } + } + } + } + } + } + ] } } } From b81f6a02652dd617a40193d118154048d4097e1c Mon Sep 17 00:00:00 2001 From: Memorysaver Date: Sat, 25 Jul 2026 21:28:43 +0800 Subject: [PATCH 05/13] =?UTF-8?q?docs(aep):=20human-alignment=20revision?= =?UTF-8?q?=209=20=E2=80=94=20completeness=20by=20construction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An independent generator/evaluator pass on the generated brief returned FAIL. Nine content defects; eight of them are the same defect wearing different clothes: the prose needed a fact the derivation had not produced, so the authoring agent supplied it from a diagram label, from ambient knowledge, or by counting manually — and the audit could not object, because its unit of check was the digit rather than the claim. Root cause: the facts plane was designed top-down (what should the brief show?) against a source carrying 483 populated key paths, of which the derivation reads about thirty. Every hole was a path nobody had looked at. D9 replaces hole-by-hole patching with four deterministic mechanisms: 1. Source census — enumerate every populated path in the plan file and classify it against a committed manifest as derived / ignored(with a reason) / unhandled. Unhandled paths carrying data are reported, and the brief states its own reading coverage. Closes the cost, files_affected, attempt_count and closure_status defects at once. 2. Claims bind, not numbers — every assertive block declares the facts it rests on; no uncited assertive block may exist; number-words count as numbers. One rule closes both the unbound numeral and the uncited causal claim. 3. Facts carry predicates, not raw fields — retries_exhausted, sign_off_withdrawn, root_cause_stated, completions_in_window. If the predicate does not exist, rule 2 forbids the sentence, so the derivation and the prose are forced to co-evolve. Corollary: a fact may not collapse ambiguity — ties are carried whole, or the prose will assert uniqueness. 4. Every tool declares its own coverage — a scanner reports what it did not cover, and no tool may imply totality. Owner rulings: classification is at path-template level (~100 entries, not 483 leaves), and an ignored entry must carry a reason rather than a checkmark. Recorded honestly: one of the nine (an unsorted changelog slice) is an ordinary bug that none of these mechanisms would have caught. Eight become structurally impossible; one was simply wrong code. Acceptance is not "the defects are gone" but "the defects cannot be authored": re-running against the reference consumer, the census must report the unhandled paths that produced them and the audit must reject the sentences that shipped. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01EDTHXC2N5mDL1DtFXopAWn --- docs/decisions/human-alignment.md | 147 ++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 8 deletions(-) diff --git a/docs/decisions/human-alignment.md b/docs/decisions/human-alignment.md index 9529e6e..fa94b8b 100644 --- a/docs/decisions/human-alignment.md +++ b/docs/decisions/human-alignment.md @@ -78,6 +78,22 @@ > records** — do not concede the ground to agent judgment. Revision 7's own > implementation violated this three times (D7). +> **Revision 9 (2026-07-25):** after an independent generator/evaluator pass on +> the generated brief returned **FAIL**. Nine content defects, and all but one +> share a single shape: **the prose needed a fact the derivation had not +> produced, so the authoring agent supplied it from a diagram label, from +> ambient knowledge, or by counting manually — and the audit could not see it, +> because its unit of check was the digit rather than the claim.** The root +> cause is that the facts plane was designed top-down (what should the brief +> show?) against a source carrying **483 populated key paths**, of which the +> derivation read about **thirty**. Revision 9 replaces hole-by-hole patching +> with four mechanisms that make the gap visible and the omission illegal (D9): +> a **source census**, **claims that bind** rather than numbers that bind, +> facts that carry **predicates** rather than raw fields, and tools that +> **declare their own coverage**. Owner rulings: the census classifies at +> **path-template level**, and an `ignored` entry must carry a **reason**, not +> a checkmark. + ## Problem AEP's planning layer captures intent and state in `product-context.yaml` — stories, @@ -416,14 +432,14 @@ Carried over from the SIBYL contract, unchanged in meaning: The generation pipeline (each phase ends in a checkable postcondition, per the deterministic-orchestration standard): -| Phase | Action | Postcondition | -| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0 · Preflight | `product-context.yaml` exists (else point to `/aep-envision`); read `docs/human-alignment/manifest.json` for the delta baseline | baseline commit known, or first-run declared | -| 1 · Derive | run `scripts/derive.mjs`: extract **facts JSON** from `product-context.yaml` + git — story counts by state and layer, the attention set (D7), the drift facts (D7), the shipped-capability inputs for band 2 (passed layer gates + their summaries), changelog entries since baseline, layer-gate status, cost roll-up — and validate it against `facts.schema.json` | facts JSON exists and validates; every fact names its YAML path | -| 1.5 · Scan | run the deterministic architecture pipeline (D3), all three scripts named in D5: `scan-workspace.mjs` (workspace-graph scan) → `arch-rules.mjs` (R1–R10 → typed IR) → `receipt-consumer.mjs` (archify validate → apply receipts → deliver), producing the domain-overview and package-graph artifacts revision-pinned to HEAD; the declared-vs-actual gap joins the drift facts (import-level dependency-cruiser diff is the later rung) | artifacts delivered `code-verified` (package level), or scanner unavailable and the view is marked degraded | -| 2 · Author | fill `assets/template.html`: no number is ever typed into markup — every one is a `data-fact=""` binding the template's renderer fills at load (see the binding rule below); narrative (PRIMER, translations, LEDGER prose) is written fresh, tense-chipped, stamped with authored-at + source commit; narrative obeys the evidence-language rule and the cold-reader authoring rules below | every section rendered or stamped | -| 3 · Audit | run `scripts/audit.mjs` for the mechanical checks (number-provenance, statically: every `data-fact` path resolves in facts JSON, and no digit appears in authored markup outside a `data-fact` element or a provenance anchor; class preflight; chip-grammar: every non-fact chipped, no fact chipped, one chip per clause; translation-anchor 1:1 — every plain sentence cites a fact id, every surfaced fact has a plain sentence; prose vocabulary-budget count) plus the judgment checks from `references/checklist.md` (vocabulary audit against the D2 closed set, evidence-language audit, glance gate, cold-reader test, so-what test) | audit passes; failures emit structured receipts; at most two correction rounds | -| 4 · Deliver | write `docs/human-alignment/brief-T