mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
* fix(docs): align question guidance with form flow * docs: reconcile stale documentation with current code * fix(docs): remove retired template metadata from guides Generated-By: looper 0.10.6 (runner=fixer, agent=codex) * fix(e2e): stabilize visual workspace helper Generated-By: looper 0.10.6 (runner=fixer, agent=codex) * fix(docs): align localized template guide metadata Generated-By: looper 0.10.6 (runner=fixer, agent=codex)
5.4 KiB
5.4 KiB
apps/daemon/src/critique/ (Critique Theater, daemon side)
Module map agents enter when they need to change anything in the critique pipeline. The user-facing feature name is Design Jury; the directory keeps the Critique Theater internal name so the product label can move without churning code paths.
Layout
| File | Responsibility |
|---|---|
config.ts |
CritiqueConfig defaults + OD_CRITIQUE_* env-var parsing. The single source of truth for thresholds, weights, max-rounds, timeouts. |
orchestrator.ts |
The state machine. Spawns a CLI session, feeds the panelist prompts in order, awaits each round's SHIP / round_end, and decides whether to continue or terminate. |
parser.ts + parsers/v1.ts |
Streaming parser that ingests the agent's stdout and yields PanelEvents. Owns the <CRITIQUE_RUN>, <PANELIST>, <SHIP> envelope. |
errors.ts |
Typed parser failures: MalformedBlockError, OversizeBlockError, MissingArtifactError. Each maps to a DegradedReason so the wire-level critique.degraded event carries the right tag. |
persistence.ts |
SQLite writes for run rows and per-round summaries (critique_runs, critique_rounds). |
artifact-writer.ts |
Disk persistence for the SHIP artifact body. Owns the byte-budget guard (ArtifactTooLargeError) and the O_NOFOLLOW path-traversal protections. |
artifact-handler.ts |
HTTP read path: GET /api/projects/:id/critique/:runId/artifact. |
interrupt-handler.ts |
Resolves the kill request from POST /api/projects/:id/critique/:runId/interrupt. |
adapter-degraded.ts |
In-memory degraded-adapter registry with 24h TTL. The orchestrator + Settings UI consult isDegraded(adapterId) before routing a run to it. |
conformance.ts |
Conformance harness entry point. The prerelease cycle calls runAdapterConformance per adapter × per brief template and tallies shipped / degraded / failed. |
conformance-history.ts |
Reads and summarizes persisted conformance history used by rollout decisions. |
ratchet.ts + rollout.ts |
Evaluate conformance evidence and resolve the current feature rollout tier. |
run-registry.ts |
Project-keyed in-process run registry used by interrupt handling. |
scoreboard.ts |
Aggregates per-adapter conformance outcomes for the status surfaces. |
spawn-inputs.ts |
Builds the isolated prompt and filesystem inputs passed to critique subprocesses. |
transcript.ts |
Persists and reads replayable critique event transcripts. |
__fixtures__/v1/ |
Canonical transcripts the parser tests + conformance harness consume (happy-3-rounds, malformed-unbalanced, missing-artifact, etc.). |
__fixtures__/adapters/ |
Synthetic adapter stubs that emit the v1 fixtures. The conformance harness wraps them in AsyncIterable<string> so the parser path is exercised end-to-end without a real model. |
Invariants
- Parser yields one
PanelEventat a time via async generator. The orchestrator drives the loop; nothing in this directory collects events into an array eagerly. - Terminal phases (
shipped,degraded,interrupted,failed) are emitted exactly once per run. The reducer treats them as sticky; duplicate ship events tripduplicate_shipinparser_warning. - Artifact bytes never travel on the wire. The SHIP event carries an
artifactRef: { projectId, artifactId }only; the byte body is written byartifact-writer.tsand fetched via the HTTP route. - Round bookkeeping is keyed by round number, not by "always the
last." A stray late panelist event from round 1 must NOT corrupt
round 2's bucket. See
withRoundin the web reducer for the parallel. - No
apps/daemon/src/agents/registry.ts. The plan refers to that path historically; the actual adapter registry isruntimes/registry.tsin this repo. Phase 10 routing extensions land here inadapter-degraded.tsinstead. - Designer weight is frozen at 0.0 until v2 cast config lands.
config.tsexposes the panel weights asCritiqueConfig.weightsbut every production deployment uses the v1 distribution (designer 0 / critic 0.4 / brand 0.2 / a11y 0.2 / copy 0.2). The v2 work is cross-package: the daemon adds per-skill weight overrides driven offod.critique.castinSKILL.mdfrontmatter (this directory) and the web Settings surface adds a per-project weight editor (apps/web/src/components/SettingsDialog.tsx). Treat the v1 weights as a wire-shape invariant rather than a tuning knob; changing them mid-v1 will break thecompositenumbers persisted incritique_runs.
When you change anything here
- The contracts in
packages/contracts/src/critique.tsare the single source of truth forPanelEvent,DegradedReason,FailedCause,ParserWarningKind. Update them before changing this directory. - The parser is the natural place to enforce schema strictness; do not
loosen it under pressure. The web
sseToPanelEventalready runs a defence-in-depth variant validator. - Add a v1 fixture under
__fixtures__/v1/for every new failure shape, and a corresponding conformance test case. - Bump
CRITIQUE_PROTOCOL_VERSIONin the contracts when the wire shape changes. Adapter conformance auto-marksdegradedon protocol-version mismatch, so this is load-bearing.
Related
- Spec:
specs/current/critique-theater.md - Plan:
specs/current/critique-theater-plan.md - User docs:
docs/critique-theater.md - Web counterpart:
apps/web/src/components/Theater/AGENTS.md