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
Metadata
Release files for taskatlas 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| taskatlas-0.0.2.tar.gz | 34.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| taskatlas-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.9 kB
Release files / taskatlas-0.0.2.tar.gz
| Download URL | taskatlas-0.0.2.tar.gz |
|---|---|
| Size | 34.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5bedba4395868b81894c6388af802dd3b0f7946ff343527e9495664cef7b2f15
|
|
BLAKE2b-256 checksum How to use checksums |
57fd76650692ed7836bb0703d8a832b0f22c6ae8035a7e4d22368877b5dada84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / taskatlas-0.0.2-py3-none-any.whl
| Download URL | taskatlas-0.0.2-py3-none-any.whl |
|---|---|
| Size | 22.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
24577e163c4a3a7d3a2890b4231b2874a6f5b6ec1564c95df13534acacf85231
|
|
BLAKE2b-256 checksum How to use checksums |
cab663eeb24910756d508a0df7d0781eb76a999c27bca71770e45a338b963cce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Security for taskatlas 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.