Usage and constraints
Usage and calculation constraints
Section titled “Usage and calculation constraints”Scope and data
Section titled “Scope and data”This package owns types, pure graph calculation and the in-memory adapter. Database adapters, schema/DDL generation, HTTP adapters and graph-aware agent execution remain in data-engine or the consuming application. TaskGraphAdapter is an interface, not a DB or network connection. Engine’s existing graph exports refer to the same functions/classes. Use explicit npm versions, not sibling aliases.
A TaskNode needs unique id, title and status; durationHours defaults to 1.
TaskEdge connects predecessorId to successorId; lagHours defaults to 0. Metadata
such as status, dueDate and assignee does not filter tasks or change scheduling.
TypeScript types do not validate incoming JSON. Validate and normalize untrusted
input at the application boundary before calling graph operations.
Supported scheduling model
Section titled “Supported scheduling model”CPM handles finish-to-start dependencies only: omitted dependencyType,
FS or FINISH_TO_START. Other types such as SS/FF/SF throw in CPM rather than
being silently treated as FS. The extensible TaskEdge type can describe other
systems; that does not mean this solver implements those systems’ constraints.
Durations must be finite and nonnegative (zero is valid), dependency lags finite,
task IDs unique, endpoints present and the graph acyclic for CPM. Negative lags
are accepted as lead times. Start times have a zero lower baseline; the algorithm
operates on elapsed hours, not dates, holidays, timezones, resource constraints or
working calendars. Validate project-specific lag/calendar rules yourself.
calculateCriticalPath and simulateDelayImpact validate these constraints;
lower-level adjacency/cycle/sort helpers assume normalized graph input and are not
full schema validators. Cycles can be inspected with detectCycles/validateAcyclic,
while CPM rejects them. Empty CPM input returns zero duration and empty schedules.
criticalPathTaskIds contains all zero-slack tasks in topological order, potentially covering several tied paths. It is not necessarily one unique path. Slack is rounded to 0.01 hour for classification. Blocker priority is a heuristic, not an optimal resource allocation plan; blockers can still be analyzed on cyclic data.
simulateDelayImpact increases one task’s duration by finite, nonnegative hours, then recomputes CPM. It does not postpone a real calendar start or persist changes. It reports downstream tasks whose early starts move, total completion delay and the new zero-slack task set. Source tasks/edges are not modified by pure analysis.
In-memory adapter and scale
Section titled “In-memory adapter and scale”InMemoryTaskGraphAdapter accepts tasks/edges or an async loadData callback. Each analysis loads the graph; the callback can fail and its error propagates. setData replaces the arrays, not an external database. Constructor/setData copy the arrays shallowly; loadGraph returns references and task objects are not deeply isolated or frozen. Avoid external mutation during analysis; supply detached, consistent snapshots when isolation is required. There is no transaction or persistent storage, authorization or cross-process synchronization.
Cycle traversal uses recursion and repeated reachability analysis can be costly. No huge-graph or hard real-time guarantee is made; measure representative graph sizes in the target runtime and bound application input. This is not a complete project scheduler or an execution dispatcher.
Tests, packaging and docs
Section titled “Tests, packaging and docs”bun run verify checks dependency boundaries, source/tests types, graph unit tests,
dual build, isolated Node/Bun ESM/CJS tarball consumers, strict NodeNext with/without
Node ambient types and a browser bundle. Known-answer CPM/lag/delay results and
invalid dependencies/cycles are covered. No live DB/HTTP/AI service is used.
JSDoc/README/guides are canonical here; apps/docs reads local workspace sources. Local
previews are explicitly unpublished. See RELEASING.md for npm CI and first release.
Negative FS lag represents a lead. Every task must finish by the overall project completion, including a predecessor that outlasts its successor. The backward pass caps every late finish at project duration. Tied critical paths return all zero-slack task IDs; that list need not describe one linear path.
For the separate date-based API see: planning.