Decompose architecture into 28 atomic implementation tasks

Break the @alkdev/taskgraph architecture specs into dependency-ordered
implementation tasks across 8 component directories: setup, schema,
error, graph, analysis, cost-benefit, frontmatter, api, and review.
Each task has clear acceptance criteria referencing specific architecture
docs. Three review tasks serve as quality gates at critical junction
points (schemas-and-errors, graph-complete, complete-library). The
dependency graph is validated acyclic with 9 topological levels enabling
significant parallelism across independent work streams.
This commit is contained in:
2026-04-27 08:30:05 +00:00
parent e592caed57
commit 131e3e929b
28 changed files with 1306 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
---
id: cost-benefit/dag-propagation
name: Implement DAG-propagation effective probability computation
status: pending
depends_on:
- cost-benefit/ev-calculation
- graph/queries
- schema/numeric-methods-and-defaults
scope: moderate
risk: high
impact: phase
level: implementation
---
## Description
Implement the DAG-propagation cost model in `src/analysis/cost-benefit.ts`. This is the core algorithmic contribution beyond the Rust CLI — it captures the structural reality that upstream failures multiply downstream damage.
Per [cost-benefit.md](../../../docs/architecture/cost-benefit.md), the algorithm:
1. Processes tasks in topological order
2. For each task with prerequisites, computes `pEffective` from intrinsic probability + upstream propagation
3. Upstream propagation: `parentP + (1 - parentP) × qualityRetention` for each parent
4. `pEffective` = intrinsic × product of all inherited quality factors
## Acceptance Criteria
- [ ] `computeEffectiveP(taskId, graph, upstreamSuccessProbs, defaultQualityRetention, propagationMode)` — internal helper
- [ ] In `dag-propagate` mode: for each task in topological order:
- Get intrinsic probability from `resolveDefaults(risk).successProbability`
- For each prerequisite, compute inherited quality: `parentP + (1 - parentP) × qualityRetention`
- `pEffective` = intrinsic × product of all inherited quality factors
- Store task's **actual** success probability for downstream propagation (use `pEffective` if this is the task's real probability)
- [ ] In `independent` mode: `pEffective = pIntrinsic` (no propagation)
- [ ] Completed tasks (`status: "completed"`): propagate with `p = 1.0` when `includeCompleted: false`
- [ ] `qualityRetention` per edge defaults to 0.9, can be overridden per-edge via `defaultQualityRetention` option or edge attributes
- [ ] Throws `CircularDependencyError` if graph is cyclic (needs topo sort)
- [ ] Unit tests: simple chain (verify compounding effect), diamond graph, independent vs dag-propagate comparison matches Python research model results, completed task exclusion/propagation semantics
## References
- docs/architecture/cost-benefit.md — DAG-propagation algorithm, qualityRetention semantics
- docs/architecture/decisions/004-workflow-cost-dag-propagation.md — ADR-004
- docs/architecture/decisions/005-no-depth-escalation-v1.md — no depth escalation in v1
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,48 @@
---
id: cost-benefit/ev-calculation
name: Implement calculateTaskEv pure function
status: pending
depends_on:
- schema/numeric-methods-and-defaults
- schema/result-types
scope: narrow
risk: low
impact: component
level: implementation
---
## Description
Implement `calculateTaskEv(p, scopeCost, impactWeight, config?): EvResult` in `src/analysis/cost-benefit.ts`. This is the pure math function — takes numeric inputs, returns EV result. No graph dependency.
Per [cost-benefit.md](../../../docs/architecture/cost-benefit.md):
```
EV = P_success × C_success + (1 - P_success) × C_fail
```
Where `C_fail = scopeCost + fallbackCost + timeLost × expectedRetries`.
## Acceptance Criteria
- [ ] `calculateTaskEv(p: number, scopeCost: number, impactWeight: number, config?: EvConfig): EvResult`
- [ ] Returns `EvResult`: `{ ev, pSuccess, expectedRetries }`
- [ ] `expectedRetries` = `(1 - p) / p` when `p > 0`, else 0 (geometric series)
- [ ] `C_fail = scopeCost * impactWeight + fallbackCost + timeLost * expectedRetries` (impactWeight scales the cost)
- [ ] `EV = p * scopeCost * impactWeight + (1-p) * C_fail`
- [ ] When `config.retries` is provided and > 0, caps `expectedRetries` at `retries`
- [ ] When `config.valueRate` is non-zero, multiplies the final EV
- [ ] Edge cases: `p = 0` (guaranteed failure), `p = 1` (guaranteed success), default config (all zeros)
- [ ] Unit tests: known calculations from the Python research model, boundary values, config variations
## References
- docs/architecture/cost-benefit.md — EV formula, EvConfig parameters, EvResult
- docs/architecture/api-surface.md — calculateTaskEv signature
- docs/architecture/schemas.md — EvConfig, EvResult schemas
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,50 @@
---
id: cost-benefit/risk-analysis
name: Implement riskPath, riskDistribution, and shouldDecomposeTask functions
status: pending
depends_on:
- cost-benefit/ev-calculation
- analysis/critical-path
- schema/numeric-methods-and-defaults
scope: moderate
risk: low
impact: component
level: implementation
---
## Description
Implement the three risk analysis functions: `riskPath`, `riskDistribution`, and `shouldDecomposeTask`. These are standalone composable functions that serve different analysis use cases.
## Acceptance Criteria
- [ ] `riskPath(graph: TaskGraph): RiskPathResult`:
- Calls `weightedCriticalPath` with weight function `riskWeight * impactWeight`
- Returns `{ path: string[], totalRisk: number }`
- `totalRisk` is the sum of weight values along the path
- [ ] `riskDistribution(graph: TaskGraph): RiskDistributionResult`:
- Groups all tasks by their `risk` attribute
- Returns `{ trivial: string[], low: string[], medium: string[], high: string[], critical: string[], unspecified: string[] }`
- Tasks with `risk: undefined` (not assessed) go in `unspecified`
- No duplicate task IDs in any bucket
- [ ] `shouldDecomposeTask(attrs: TaskGraphNodeAttributes): DecomposeResult`:
- Pure function — takes node attributes (not a graph)
- Internally calls `resolveDefaults` for `risk` and `scope` (nullable fields)
- Flags decomposition when: risk >= "high" OR scope >= "broad"
- Returns `{ shouldDecompose: boolean, reasons: string[] }`
- Unassessed tasks (null/undefined risk or scope) are never flagged — default values are below threshold
- Provides specific reasons: e.g., `"risk: high — failure probability 0.35"`, `"scope: broad — cost estimate 4.0"`
- [ ] Unit tests for all three functions with known inputs/outputs
## References
- docs/architecture/api-surface.md — risk analysis functions
- docs/architecture/cost-benefit.md — riskPath, riskDistribution, shouldDecomposeTask, decomposition threshold
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,45 @@
---
id: cost-benefit/workflow-cost
name: Implement workflowCost orchestration function
status: pending
depends_on:
- cost-benefit/dag-propagation
- graph/queries
scope: moderate
risk: medium
impact: component
level: implementation
---
## Description
Implement `workflowCost(graph: TaskGraph, options?: WorkflowCostOptions): WorkflowCostResult` in `src/analysis/cost-benefit.ts`. This orchestrates the per-task EV calculations, handles DAG propagation, and enriches results with `taskId` and `name` from the graph.
## Acceptance Criteria
- [ ] `workflowCost` accepts `WorkflowCostOptions` with optional: `includeCompleted`, `limit`, `propagationMode`, `defaultQualityRetention`
- [ ] Default propagation mode: `"dag-propagate"` per ADR-004
- [ ] Default `defaultQualityRetention`: 0.9
- [ ] Each task in result includes: `taskId`, `name`, `ev`, `pIntrinsic`, `pEffective`, `probability` (= `pEffective`), `scopeCost`, `impactWeight`
- [ ] `totalEv`: sum of all task EVs (excluding completed tasks from output when `includeCompleted: false`)
- [ ] `averageEv`: `totalEv / tasks.length`
- [ ] `propagationMode`: reflected in result
- [ ] When `includeCompleted: false`: completed tasks excluded from `tasks` array but remain in propagation chain with p=1.0
- [ ] When `includeCompleted: false`: only `"completed"` status triggers exclusion; `"failed"` and `"blocked"` are always included
- [ ] When `limit` is set: returns at most `limit` tasks (sorted by EV descending? or topological order? spec says "limits the number of tasks in the result" — use topological order with limit)
- [ ] Throws `CircularDependencyError` if graph is cyclic
- [ ] Unit tests: full workflow cost calculation, independent vs dag-propagate comparison, excludeCompleted scenarios, limit behavior
## References
- docs/architecture/cost-benefit.md — workflow cost, skip-completed semantics
- docs/architecture/api-surface.md — workflowCost signature, WorkflowCostOptions
- docs/architecture/decisions/004-workflow-cost-dag-propagation.md — ADR-004
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion