Decompose monolithic architecture.md into modular docs/architecture/ documents

The 751-line architecture.md violated the SDD process modular documentation
target (~500 lines). It also had duplicate TaskGraph class definitions (one
monolith, one decomposed) that directly contradicted each other, and embedded
consumer-specific tool dispatch mappings that belong in downstream projects.

Changes:
- Split into 8 focused documents + 7 ADR records + redirect page
- Removed the monolithic TaskGraph class (kept only decomposed version)
- Moved CLI→plugin dispatch mapping out (belongs in plugin architecture)
- Extracted implementation code (frontmatter splitter, findCycles, DAG
  propagation) into WHAT/WHY descriptions per architect role spec
- Added proper ADR format for all resolved design decisions
- Fixed review issues: C_fail mapping, DuplicateNodeError/DuplicateEdgeError
  types, ValidationError/GraphValidationError definitions, mutation error
  handling contract, enum naming convention, validation timing clarification
This commit is contained in:
2026-04-26 06:38:52 +00:00
parent bac335274d
commit bde1cc4e70
16 changed files with 1264 additions and 748 deletions

View File

@@ -0,0 +1,89 @@
---
status: draft
last_updated: 2026-04-26
---
# Build & Distribution
Dependencies, project structure, build targets, and performance notes.
## Dependencies
| Package | Purpose |
|---------|---------|
| `graphology` | Directed graph data structure + event emitter |
| `graphology-dag` | hasCycle, topologicalSort, topologicalGenerations |
| `graphology-metrics` | betweenness centrality (bottleneck) |
| `graphology-components` | strongly-connected components (findCycles pre-check) |
| `graphology-operators` | subgraph extraction |
| `@alkdev/typebox` | Schema definition, static types, runtime validation |
| `yaml` | YAML 1.2 parser (zero dependencies, no known CVEs) |
## Project Structure
```
taskgraph_ts/
├── package.json
├── tsconfig.json
├── src/
│ ├── index.ts # Public API surface, re-exports
│ ├── schema/
│ │ ├── index.ts # Re-exports all schemas
│ │ ├── enums.ts # TaskScope, TaskRisk, TaskImpact, TaskLevel, TaskStatus, TaskPriority
│ │ ├── task.ts # TaskInput, DependencyEdge schemas
│ │ ├── graph.ts # TaskGraphNodeAttributes, TaskGraphEdgeAttributes, SerializedGraph
│ │ └── results.ts # RiskPathResult, DecomposeResult, WorkflowCostResult, RiskDistributionResult
│ ├── graph/
│ │ ├── index.ts # TaskGraph class
│ │ ├── construction.ts # fromTasks, fromRecords, fromJSON, incremental building
│ │ ├── queries.ts # hasCycles, findCycles, topologicalOrder, dependencies, dependents
│ │ └── mutation.ts # removeTask, removeDependency, updateTask, updateEdgeAttributes
│ ├── analysis/
│ │ ├── index.ts # Re-exports
│ │ ├── critical-path.ts # criticalPath, weightedCriticalPath
│ │ ├── bottleneck.ts # bottlenecks (graphology betweenness)
│ │ ├── risk.ts # riskPath, riskDistribution
│ │ ├── cost-benefit.ts # calculateTaskEv, workflowCost, computeEffectiveP
│ │ ├── decompose.ts # shouldDecomposeTask
│ │ └── defaults.ts # resolveDefaults, enum numeric methods
│ ├── frontmatter/
│ │ ├── index.ts # parseFrontmatter, parseTaskFile, parseTaskDirectory, serializeFrontmatter
│ │ ├── parse.ts # YAML/frontmatter parsing + typebox validation
│ │ └── serialize.ts # TaskInput → markdown with frontmatter
│ └── error/
│ └── index.ts # TaskgraphError, TaskNotFoundError, CircularDependencyError, InvalidInputError
├── test/
│ ├── graph.test.ts
│ ├── analysis.test.ts
│ ├── schema.test.ts
│ ├── frontmatter.test.ts
│ └── cost-benefit.test.ts
└── docs/
└── architecture/ # This architecture document set
```
The structure reflects the decomposition decision: `src/analysis/` contains standalone functions, `src/graph/` contains the TaskGraph data class. This is not an accident — it enforces at the filesystem level that analysis functions are separate from the graph class.
## Build & Distribution
- **Package**: `@alkdev/taskgraph` on npm
- **Module**: ESM primary, CJS compat
- **Targets**: Node 18+, Deno, Bun — pure JS, no native addons
- **Build**: `tsc` for declarations + bundler for distribution
- **No platform-specific binaries** — this is the whole point of the pivot from NAPI/Rust
## Performance Notes
From graphology's performance tips:
- Prefer callback iteration (`forEachNode`, `forEachEdge`) over array-returning methods (`nodes()`, `edges()`) when iterating
- Use `addEdgeWithKey` with deterministic `${source}->${target}` keys instead of `addEdge` to skip the automatic key generation overhead — see [ADR-006](decisions/006-deterministic-edge-keys.md)
- Avoid callback nesting in hot loops; hoist inner callbacks
- For bulk construction, `graph.import(serializedData)` is faster than N individual add calls
Realistic task graphs (10200 nodes) make all of this academic, but the patterns are free to adopt.
## Constraints
- **Pure JavaScript** — no Rust, no WASM, no native addons. This is non-negotiable — it's the core design decision.
- **ESM primary** — CJS compat is a distribution concern, not a design choice. Consumers should import as ESM.
- **No platform-specific binaries** — the library must work in Node, Deno, and Bun without compilation steps.