Milestone: Delivery Plan: Riviere Extraction Workflows V1 — M4 (D4.2)
PRD: docs/project/PRD/riviere-extraction-workflows-v1/PRD.md §§1, 2, 3, 4, 5, 6
Architecture: docs/project/PRD/riviere-extraction-workflows-v1/ARCH.md §§3, 4, 6
Delivery plan: docs/project/PRD/riviere-extraction-workflows-v1/delivery.md §2, D4.2
Problem
The current Rivière graph-building process is made up of several manual steps that must be performed in order. This works for first-time learning and exploration, but once a user has created their first graph and wants to rebuild it inside a codebase, they must remember the steps or create their own custom scripts. That friction makes the process easy to forget, harder to repeat, and difficult to rely on in automated flows such as CI. At the project level, it risks Rivière feeling “like a toy” rather than a tool that can be set up in a project and “just works reliably”.
This ticket covers run-log visibility. The PRD requires clear stage progress and newline-delimited structured JSON run logs so users can understand what happened, inspect failures, fix the root cause, and re-run the workflow.
This slice matters because fail-fast workflows are only reliable when the user can see which stage failed and why.
Solution
Write one NDJSON run log for each workflow run and failure path. Logs must use searchable event types and include the approved lifecycle, stage, graph-write, completion, and failure events.
Agreed target architecture and design
Full architecture context
Read docs/project/PRD/riviere-extraction-workflows-v1/ARCH.md for the full approved architecture context and scope. This ticket is not a replacement for ARCH.md.
Target components, boundaries, and responsibilities
runId is generated once at command start as a sortable UTC timestamp plus random suffix, for example 20260505T182233Z-a1b2c3d4.
- The run log destination is
{runLog.directory}/{workflowName}/{runId}.ndjson, resolved under projectRoot.
- The CLI boundary writes run logs for successful runs, workflow validation failures, referenced config failures, extraction failures, validation failures, graph write failures, and failed runs.
- Run logs are written even when graph output is not written.
- A failed run never updates
graph.outputPath.
- Each NDJSON line is one JSON object with at least
{ "type", "timestamp", "runId", "workflowName", "level" }.
- Required event types are
WorkflowStarted, WorkflowValidationFailed, StageStarted, StageCompleted, StageFailed, GraphWriteStarted, GraphWriteCompleted, WorkflowCompleted, and WorkflowFailed.
- Stage events include
stageName, stageType, and stageIndex.
- Failure events include
reason, errorCode, and any relevant configPath or outputPath.
- If the log cannot be created before stages run, the command fails before extraction and leaves the graph unchanged.
Code/config/flow from ARCH.md
createWorkflowRunCommand
├─ createRunWorkflowInput(options)
├─ RunWorkflow.execute(input)
│ ├─ RiviereProjectRepository.load({ projectRoot: input.projectRoot, workflowName: input.workflowName })
│ │ ├─ WorkflowDefinitionFile.read(projectRoot, workflowName)
│ │ ├─ GraphOptions.fromWorkflowDefinition(definition.graph)
│ │ ├─ load extraction config/source state for each extract stage
│ │ ├─ new ExtractionStage(stageName, resolvedConfig, moduleContexts, repositoryName)
│ │ └─ RiviereProject.create(projectRoot, workflowName, graphOptions, stagePlan, extractionStages)
│ └─ RiviereProject.rebuildGraph()
│ ├─ RiviereBuilder.new(graphOptions)
│ ├─ ExtractComponentsForGraph.execute(extractionStage, { allowIncomplete: false })
│ ├─ ApplyExtractionToGraph.applyComponents(builder, stageName, repository, components)
│ ├─ DetectExtractionConnections.execute(extractionStage, allComponents, { allowIncomplete: false })
│ ├─ ApplyExtractionToGraph.applyLinks(builder, stageName, links, externalLinks)
│ ├─ RiviereBuilder.validate()
│ └─ RiviereBuilder.build()
└─ presentWorkflowRunResult(result)
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow.ts
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow/present-workflow-run-result.ts
Role and location decisions
| Proposed Element |
Kind |
Role |
Sublocation |
Confidence |
Notes |
presentWorkflowRunResult |
function |
cli-output-formatter / entrypoint-local output writer role from approved architecture |
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow |
High |
CLI boundary output handler that writes NDJSON run logs. |
| Run log event model |
type/interface |
command-use-case-result-value or approved existing result-value role |
packages/riviere-cli/src/features/workflow/commands or approved result boundary |
Medium |
Carries events from the run result without moving CLI file writing into domain code. |
RunWorkflowResult |
type/interface |
command-use-case-result |
packages/riviere-cli/src/features/workflow/commands |
High |
Carries graph build success/failure, run events, run log path, and failure detail. |
If implementation requires a role or location not approved by .riviere or ARCH.md, stop and ask for approval before adding it.
Structural concerns and forbidden alternatives
- Do not write run logs from
RiviereProject.
- Do not write run logs from
RunWorkflow.
- Do not add workflow presentation files under the older
infra/cli/output pattern.
- Do not add CI-specific observability, annotations, job summaries, or reporting.
- Do not omit failure logs when graph output is not written.
- Do not hide missing log fields behind fallback values.
Design challenge instruction
If implementation reveals the agreed design is impractical, incomplete, or sub-optimal, stop and push back. Do not silently implement a different design.
What "done" looks like
Product
- Each workflow run creates one NDJSON run log.
- Each log line is one JSON object.
- Each event includes at least
type, timestamp, runId, workflowName, and level.
- Required event types are emitted:
WorkflowStarted, WorkflowValidationFailed, StageStarted, StageCompleted, StageFailed, GraphWriteStarted, GraphWriteCompleted, WorkflowCompleted, and WorkflowFailed.
- Stage events include
stageName, stageType, and stageIndex.
- Failure events include
reason, errorCode, and relevant configPath or outputPath.
- Logs are written for successful runs, validation failures, referenced config failures, extraction failures, stage failures, graph write failures, and completed failures.
- If the log cannot be created before stages run, the command fails before extraction.
Design
- Run-log writing happens at the CLI boundary through the approved entrypoint-local workflow presentation/output handling.
RiviereProject returns events and failure details but does not write log files.
RunWorkflow returns results but does not write log files.
- Run logs are written even when graph output is not written.
- Failed runs never update
graph.outputPath.
Quality
- Tests inspect NDJSON output for required event fields.
- Tests inspect NDJSON output for required event types.
- Tests inspect success logs and failure logs.
- Tests prove log creation failure stops before extraction.
- Tests assert exact JSON event values where inputs are deterministic.
- No ticket-specific performance, accessibility, security, privacy, or compatibility criteria were identified beyond repository standards.
Implementation guidelines
Change areas
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow.ts
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow/present-workflow-run-result.ts
packages/riviere-cli/src/features/workflow/commands/run-workflow-result.ts
- Tests for NDJSON run logs and log failure paths.
- Avoid
RiviereProject file writing.
- Avoid
RunWorkflow file writing.
Relevant repository rules
docs/conventions/software-design.md — SD-001 Fail-fast over silent fallbacks.
docs/conventions/software-design.md — SD-002 No any or unsafe type assertions.
docs/conventions/software-design.md — SD-003 Make illegal states unrepresentable.
docs/conventions/software-design.md — SD-005 Intention-revealing names only.
docs/conventions/software-design.md — SD-007 Use Zod for runtime validation at boundaries.
docs/conventions/software-design.md — SD-020 Prefer immutability.
docs/conventions/testing.md — TS-001 Test names describe outcomes.
docs/conventions/testing.md — TS-002 Assertions must match test titles.
docs/conventions/testing.md — TS-003 Assert specific values.
docs/conventions/testing.md — TS-004 One concept per test.
docs/conventions/testing.md — TS-005 Bugs cluster together.
Relevant architecture memories
project-memory/architecture/memories/ddd-modelling-trade-offs-from-riviere-workflows.md — CLI output policy belongs at the CLI boundary.
project-memory/architecture/memories/rejected-workflow-use-case-dumping-case-study.md — domain results must not expose command/use-case conversion, and use cases must not take over output writing.
Lint, role-check, and test expectations
- This ticket touches role-enforced TypeScript. Expect lint and role-check feedback and use it to improve the design rather than working around it.
- Exact package-level lint, role-check, and test commands were not named in the approved PRD, architecture, delivery plan,
.riviere role configuration, or convention files used for task creation.
- Tests must parse NDJSON and assert specific event objects, not only assert file existence.
Dependencies
How to verify
- Test review confirms NDJSON output contains required event fields.
- Test review confirms NDJSON output contains all required event types.
- Test review confirms success logs and failure logs are covered.
- Test review confirms log creation failure stops before extraction.
- Reviewer inspection confirms log writing is not inside
RiviereProject or RunWorkflow.
- Reviewer inspection confirms workflow presentation/output is not added under the older
infra/cli/output pattern.
- Reviewer inspection confirms no CI-specific observability, annotations, job summaries, or reporting was added.
Things this ticket must not do
- Do not add CI-specific observability, annotations, job summaries, or reporting.
- Do not write run logs from
RiviereProject.
- Do not write run logs from
RunWorkflow.
- Do not add presentation/output files under the older
infra/cli/output pattern.
- Do not add plan-first/preview mode.
- Do not add arbitrary shell-command stages or generic task-runner behaviour.
Glossary
Source glossary: docs/architecture/domain-terminology/contextive/definitions.glossary.yml.
- Component: A discrete unit of software functionality in a Riviere graph. Has a type, belongs to a domain, and connects to other components via links.
- Link: A directed connection between two components, representing a call, dependency, or event flow. Has a source and target component ID, and optionally a type (sync/async).
Milestone: Delivery Plan: Riviere Extraction Workflows V1 — M4 (D4.2)
PRD: docs/project/PRD/riviere-extraction-workflows-v1/PRD.md §§1, 2, 3, 4, 5, 6
Architecture: docs/project/PRD/riviere-extraction-workflows-v1/ARCH.md §§3, 4, 6
Delivery plan: docs/project/PRD/riviere-extraction-workflows-v1/delivery.md §2, D4.2
Problem
This ticket covers run-log visibility. The PRD requires clear stage progress and newline-delimited structured JSON run logs so users can understand what happened, inspect failures, fix the root cause, and re-run the workflow.
This slice matters because fail-fast workflows are only reliable when the user can see which stage failed and why.
Solution
Write one NDJSON run log for each workflow run and failure path. Logs must use searchable event types and include the approved lifecycle, stage, graph-write, completion, and failure events.
Agreed target architecture and design
Full architecture context
Read
docs/project/PRD/riviere-extraction-workflows-v1/ARCH.mdfor the full approved architecture context and scope. This ticket is not a replacement forARCH.md.Target components, boundaries, and responsibilities
runIdis generated once at command start as a sortable UTC timestamp plus random suffix, for example20260505T182233Z-a1b2c3d4.{runLog.directory}/{workflowName}/{runId}.ndjson, resolved underprojectRoot.graph.outputPath.{ "type", "timestamp", "runId", "workflowName", "level" }.WorkflowStarted,WorkflowValidationFailed,StageStarted,StageCompleted,StageFailed,GraphWriteStarted,GraphWriteCompleted,WorkflowCompleted, andWorkflowFailed.stageName,stageType, andstageIndex.reason,errorCode, and any relevantconfigPathoroutputPath.Code/config/flow from ARCH.md
Role and location decisions
presentWorkflowRunResultcli-output-formatter/ entrypoint-local output writer role from approved architecturepackages/riviere-cli/src/features/workflow/entrypoint/run-workflowcommand-use-case-result-valueor approved existing result-value rolepackages/riviere-cli/src/features/workflow/commandsor approved result boundaryRunWorkflowResultcommand-use-case-resultpackages/riviere-cli/src/features/workflow/commandsIf implementation requires a role or location not approved by
.riviereorARCH.md, stop and ask for approval before adding it.Structural concerns and forbidden alternatives
RiviereProject.RunWorkflow.infra/cli/outputpattern.Design challenge instruction
What "done" looks like
Product
type,timestamp,runId,workflowName, andlevel.WorkflowStarted,WorkflowValidationFailed,StageStarted,StageCompleted,StageFailed,GraphWriteStarted,GraphWriteCompleted,WorkflowCompleted, andWorkflowFailed.stageName,stageType, andstageIndex.reason,errorCode, and relevantconfigPathoroutputPath.Design
RiviereProjectreturns events and failure details but does not write log files.RunWorkflowreturns results but does not write log files.graph.outputPath.Quality
Implementation guidelines
Change areas
packages/riviere-cli/src/features/workflow/entrypoint/run-workflow.tspackages/riviere-cli/src/features/workflow/entrypoint/run-workflow/present-workflow-run-result.tspackages/riviere-cli/src/features/workflow/commands/run-workflow-result.tsRiviereProjectfile writing.RunWorkflowfile writing.Relevant repository rules
docs/conventions/software-design.md— SD-001 Fail-fast over silent fallbacks.docs/conventions/software-design.md— SD-002 Noanyor unsafe type assertions.docs/conventions/software-design.md— SD-003 Make illegal states unrepresentable.docs/conventions/software-design.md— SD-005 Intention-revealing names only.docs/conventions/software-design.md— SD-007 Use Zod for runtime validation at boundaries.docs/conventions/software-design.md— SD-020 Prefer immutability.docs/conventions/testing.md— TS-001 Test names describe outcomes.docs/conventions/testing.md— TS-002 Assertions must match test titles.docs/conventions/testing.md— TS-003 Assert specific values.docs/conventions/testing.md— TS-004 One concept per test.docs/conventions/testing.md— TS-005 Bugs cluster together.Relevant architecture memories
project-memory/architecture/memories/ddd-modelling-trade-offs-from-riviere-workflows.md— CLI output policy belongs at the CLI boundary.project-memory/architecture/memories/rejected-workflow-use-case-dumping-case-study.md— domain results must not expose command/use-case conversion, and use cases must not take over output writing.Lint, role-check, and test expectations
.riviererole configuration, or convention files used for task creation.Dependencies
How to verify
RiviereProjectorRunWorkflow.infra/cli/outputpattern.Things this ticket must not do
RiviereProject.RunWorkflow.infra/cli/outputpattern.Glossary
Source glossary:
docs/architecture/domain-terminology/contextive/definitions.glossary.yml.