A lean Python library for representing goals, tasks, relationships, priority, evolution, and history.
Project description
taskatlas
A lean Python library for representing goals, tasks, relationships, priority, evolution, and history.
What is this?
taskatlas gives you a clean, Pythonic object model for tracking work. It sits in the space between a simple task list and an enterprise issue tracker — expressive enough to model real project structure, lightweight enough to feel like writing regular Python.
An Atlas is a navigable world of:
- Goals — intended outcomes (what you're trying to achieve)
- Tasks — actionable work (what needs to be done)
- Relationships — typed links between entities (dependencies, blockers, support)
- History — automatic event records of every meaningful change
- Views — board, tree, queue, and summary representations of the current state
The library has zero external dependencies. It runs on Python 3.10+ using only the standard library.
Install
pip install taskatlas
For development (includes pytest):
git clone https://github.com/jrolf/taskatlas.git
cd taskatlas
pip install -e ".[dev]"
Quick Example
import taskatlas as ta
# Create an atlas
atlas = ta.Atlas({"name": "My Project"})
# Define a goal — an intended outcome
goal = ta.Goal({
"title": "Launch the public API",
"summary": "Ship a stable, documented v1.",
"status": "active",
"priority": "high",
"tags": ["api", "launch"],
})
atlas.add_goal(goal)
# Add tasks — actionable work
design = goal.add_task({
"title": "Design endpoint schema",
"stage": "active",
"priority": "high",
})
tests = goal.add_task({
"title": "Write integration tests",
"stage": "ready",
"priority": "high",
})
# Decompose complex tasks into subtasks
design.add_task({"title": "Define auth endpoints", "stage": "done"})
design.add_task({"title": "Define data endpoints", "stage": "active"})
# Model dependencies with typed links
tests.link(design, kind="depends_on")
# Move tasks through stages
design.move("review", reason="Implementation complete")
# Add notes to capture context
design.note("Using OpenAPI 3.1 for all endpoint specs.")
# Check goal progress
print(goal.progress())
# {'goal_id': 'g-...', 'task_count': 2, 'by_stage': {'review': 1, 'ready': 1},
# 'done_count': 0, 'done_ratio': 0.0, ...}
# View the board
print(atlas.board())
# Inspect history — every mutation is recorded automatically
for event in atlas.recent(limit=5):
print(f"{event.event_type}: {event.reason or ''}")
# Save the entire atlas to JSON
atlas.save("project.json")
# Reload it later — everything is preserved
atlas2 = ta.Atlas.load("project.json")
Core Concepts
Atlas
The root container. It owns all goals, tasks, links, and events. It's the single object you serialize and restore.
atlas = ta.Atlas({"name": "Q3 Roadmap"})
Goal
A higher-order intended outcome. Goals have statuses: proposed, active, paused, achieved, archived.
goal = ta.Goal({"title": "Improve reliability", "status": "active", "priority": "high"})
atlas.add_goal(goal)
Task
An actionable work unit. Tasks have stages: inbox, ready, active, blocked, review, done, archived.
task = ta.Task({"title": "Add retry logic", "stage": "ready", "priority": "high"})
atlas.add_task(task)
Containment vs. Links
These are two distinct relationship types that are never conflated:
Containment is structural nesting — subtasks under tasks, subgoals under goals, tasks attached to goals:
goal.add_task(task) # attach task to goal
task.add_task(subtask) # nest subtask under task
goal.add_goal(subgoal) # nest subgoal under goal
Links are typed cross-references — dependencies, blockers, and other semantic relationships:
task_a.link(task_b, kind="depends_on")
task_c.link(task_d, kind="blocks")
goal.link(other_goal, kind="supports")
Available link kinds: depends_on, blocks, relates_to, supports, duplicates, derived_from, conflicts_with.
Notes
Append-only, timestamped annotations on any goal or task:
task.note("Switched approach after profiling showed the bottleneck.")
task.note("Results look good.", meta={"runtime_ms": 340})
Automatic History
Every mutation generates an Event — stage changes, status changes, priority changes, notes, links, attachments. You never manually log history; the library does it.
task.history() # per-entity, newest first
atlas.get_events(limit=20) # global, newest first
atlas.recent(limit=10) # shortcut for recent activity
Filtering and Retrieval
Simple keyword arguments, conjunctive (AND) logic:
atlas.get_tasks(stage="active", priority="high")
atlas.get_tasks(tags=["backend"], order_by="priority")
atlas.get_tasks(goal_id=goal.id, blocked=True)
atlas.get_tasks(title_contains="auth")
atlas.get_goals(status="active")
atlas.get_goals(priority="high", tags=["core"])
Archived items are excluded by default. Use archived=True to query them explicitly.
Views
Four built-in views return structured Python data (dicts and lists), ready for rendering however you need:
| Method | Returns | Purpose |
|---|---|---|
atlas.board() |
Tasks grouped by stage | Kanban-style workflow view |
atlas.tree() |
Nested goal/task hierarchy | Structural overview |
atlas.queue() |
Priority-sorted actionable tasks | "What should I do next?" |
atlas.summary() |
Aggregate counts and recent events | Dashboard / status check |
Each goal and task also has a .context() method that returns a focused situational summary:
task.context() # compact: id, title, stage, priority, latest note
task.context(mode="full") # everything: links, notes, events, parent/children
goal.context(mode="full") # includes progress snapshot
Serialization
Full round-trip serialization to JSON files or JSON-compatible dicts:
# File-based (recommended)
atlas.save("atlas.json")
atlas = ta.Atlas.load("atlas.json")
# Dict-based
payload = atlas.to_dict() # atlas → dict
atlas = ta.Atlas.from_dict(payload) # dict → atlas
Everything is preserved: IDs, relationships, notes, links, events, timestamps, metadata.
Project Structure
taskatlas/
├── __init__.py # Public API: Atlas, Goal, Task, Link, Event
├── _atlas.py # Atlas container and registry
├── _goal.py # Goal class
├── _task.py # Task class
├── _base.py # Shared WorkItem base class
├── _link.py # Typed relationship model
├── _event.py # Historical event model
├── _filtering.py # Query and sort helpers
├── _views.py # Board, tree, queue, summary renderers
├── _identity.py # ID generation
└── _types.py # Constants and defaults
Tutorials
The tutorials/ directory contains detailed walkthroughs:
- Quickstart — Your first atlas, goals, tasks, and board
- Modeling a Real Project — End-to-end example with a data platform
- Relationships and Structure — Containment vs. links in depth
- History and Evolution — Automatic events and audit trails
- Views and Context — Board, tree, queue, summary, and context()
- Persistence and Programmatic Use — Serialization, agents, and automation
- Filtering and Retrieval — Every filter option with examples
Running Tests
pytest
The test suite contains 213 tests covering all modules, relationships, history, views, and serialization round-trips.
Design Philosophy
- Goals are not tasks. Goals represent intended outcomes. Tasks represent work. They have different lifecycles and different semantics.
- Containment is not linking. Subtask nesting is structural. Dependencies and blockers are cross-references. These are kept separate.
- History is automatic. Every meaningful mutation creates an event. You never have to manually log what happened.
- Retrieval returns context, not rows. The library should feel like asking a colleague, not querying a database.
- The board is a view, not the ontology. Tasks may move through stages, but the underlying reality is richer than columns on a board.
- Stay lean. Zero dependencies. Small API surface. No enterprise ceremony.
Contributing
Contributions are welcome. Please read CONTRIBUTING.md for the branch model, how to run tests, and PR guidelines.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file taskatlas-0.0.2.tar.gz.
File metadata
- Download URL: taskatlas-0.0.2.tar.gz
- Upload date:
- Size: 34.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5bedba4395868b81894c6388af802dd3b0f7946ff343527e9495664cef7b2f15
|
|
| MD5 |
07c2f37480854b477be410ada61022eb
|
|
| BLAKE2b-256 |
57fd76650692ed7836bb0703d8a832b0f22c6ae8035a7e4d22368877b5dada84
|
File details
Details for the file taskatlas-0.0.2-py3-none-any.whl.
File metadata
- Download URL: taskatlas-0.0.2-py3-none-any.whl
- Upload date:
- Size: 22.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24577e163c4a3a7d3a2890b4231b2874a6f5b6ec1564c95df13534acacf85231
|
|
| MD5 |
48283a922dbffdf04c495f69c0d4b273
|
|
| BLAKE2b-256 |
cab663eeb24910756d508a0df7d0781eb76a999c27bca71770e45a338b963cce
|