lattice-tracker 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. lattice_tracker-0.1.0/.gitattributes +1 -0
  2. lattice_tracker-0.1.0/.github/workflows/ci.yml +81 -0
  3. lattice_tracker-0.1.0/.gitignore +38 -0
  4. lattice_tracker-0.1.0/CLAUDE.md +415 -0
  5. lattice_tracker-0.1.0/Decisions.md +515 -0
  6. lattice_tracker-0.1.0/FutureFeatures.md +110 -0
  7. lattice_tracker-0.1.0/LICENSE +21 -0
  8. lattice_tracker-0.1.0/Makefile +22 -0
  9. lattice_tracker-0.1.0/PKG-INFO +254 -0
  10. lattice_tracker-0.1.0/Philosophy.md +246 -0
  11. lattice_tracker-0.1.0/Philosophy_v2.md +258 -0
  12. lattice_tracker-0.1.0/Philosophy_v3.md +103 -0
  13. lattice_tracker-0.1.0/ProjectRequirements_v1.md +609 -0
  14. lattice_tracker-0.1.0/README.md +221 -0
  15. lattice_tracker-0.1.0/docs/getting-started.md +344 -0
  16. lattice_tracker-0.1.0/docs/integration-claude-code.md +131 -0
  17. lattice_tracker-0.1.0/docs/integration-codex.md +169 -0
  18. lattice_tracker-0.1.0/docs/integration-mcp.md +307 -0
  19. lattice_tracker-0.1.0/docs/mcp-listing.md +254 -0
  20. lattice_tracker-0.1.0/docs/needs-human-and-next-guide.md +274 -0
  21. lattice_tracker-0.1.0/docs/user-guide.md +797 -0
  22. lattice_tracker-0.1.0/notes/cube-code-review-prompt.md +51 -0
  23. lattice_tracker-0.1.0/notes/cube-impl/core-rendering.js +458 -0
  24. lattice_tracker-0.1.0/notes/cube-impl/lifecycle-routing.js +290 -0
  25. lattice_tracker-0.1.0/notes/cube-impl/resilience.js +357 -0
  26. lattice_tracker-0.1.0/notes/cube-impl/styles.css +320 -0
  27. lattice_tracker-0.1.0/notes/cube-impl/tooltip-inspection.js +597 -0
  28. lattice_tracker-0.1.0/notes/cube-plan-review-prompt.md +144 -0
  29. lattice_tracker-0.1.0/notes/cube-vision.md +360 -0
  30. lattice_tracker-0.1.0/notes/prompt-open-source-blitz.md +142 -0
  31. lattice_tracker-0.1.0/notes/prompt-triage-stale.md +73 -0
  32. lattice_tracker-0.1.0/notes/review-lat27-claude.md +55 -0
  33. lattice_tracker-0.1.0/notes/review-lat27-codex.md +11 -0
  34. lattice_tracker-0.1.0/notes/review-lat28-claude.md +104 -0
  35. lattice_tracker-0.1.0/notes/review-lat28-codex.md +25 -0
  36. lattice_tracker-0.1.0/notes/review-lat29-claude.md +147 -0
  37. lattice_tracker-0.1.0/notes/review-lat29-codex.md +30 -0
  38. lattice_tracker-0.1.0/notes/review-lat30-claude.md +202 -0
  39. lattice_tracker-0.1.0/notes/review-lat30-codex.md +36 -0
  40. lattice_tracker-0.1.0/notes/review-sweep-claude.md +143 -0
  41. lattice_tracker-0.1.0/notes/review-sweep-codex.md +47 -0
  42. lattice_tracker-0.1.0/notes/stats-demo/assemble.sh +146 -0
  43. lattice_tracker-0.1.0/notes/stats-demo/demo.html +5707 -0
  44. lattice_tracker-0.1.0/notes/stats-demo/section-1.html +704 -0
  45. lattice_tracker-0.1.0/notes/stats-demo/section-2.html +961 -0
  46. lattice_tracker-0.1.0/notes/stats-demo/section-3.html +844 -0
  47. lattice_tracker-0.1.0/notes/stats-demo/section-4.html +1593 -0
  48. lattice_tracker-0.1.0/notes/stats-demo/section-5.html +1500 -0
  49. lattice_tracker-0.1.0/prompts/outstanding-implementation-items.md +158 -0
  50. lattice_tracker-0.1.0/pyproject.toml +73 -0
  51. lattice_tracker-0.1.0/research/code-factory-ryan-carson.md +163 -0
  52. lattice_tracker-0.1.0/research/distribution-strategy.md +595 -0
  53. lattice_tracker-0.1.0/research/openclaw-ecosystem.md +597 -0
  54. lattice_tracker-0.1.0/src/lattice/__init__.py +3 -0
  55. lattice_tracker-0.1.0/src/lattice/cli/__init__.py +1 -0
  56. lattice_tracker-0.1.0/src/lattice/cli/archive_cmds.py +236 -0
  57. lattice_tracker-0.1.0/src/lattice/cli/artifact_cmds.py +232 -0
  58. lattice_tracker-0.1.0/src/lattice/cli/dashboard_cmd.py +56 -0
  59. lattice_tracker-0.1.0/src/lattice/cli/helpers.py +185 -0
  60. lattice_tracker-0.1.0/src/lattice/cli/integrity_cmds.py +883 -0
  61. lattice_tracker-0.1.0/src/lattice/cli/link_cmds.py +222 -0
  62. lattice_tracker-0.1.0/src/lattice/cli/main.py +482 -0
  63. lattice_tracker-0.1.0/src/lattice/cli/migration_cmds.py +187 -0
  64. lattice_tracker-0.1.0/src/lattice/cli/query_cmds.py +726 -0
  65. lattice_tracker-0.1.0/src/lattice/cli/stats_cmds.py +134 -0
  66. lattice_tracker-0.1.0/src/lattice/cli/task_cmds.py +694 -0
  67. lattice_tracker-0.1.0/src/lattice/cli/weather_cmds.py +463 -0
  68. lattice_tracker-0.1.0/src/lattice/core/__init__.py +1 -0
  69. lattice_tracker-0.1.0/src/lattice/core/artifacts.py +81 -0
  70. lattice_tracker-0.1.0/src/lattice/core/config.py +176 -0
  71. lattice_tracker-0.1.0/src/lattice/core/events.py +126 -0
  72. lattice_tracker-0.1.0/src/lattice/core/ids.py +93 -0
  73. lattice_tracker-0.1.0/src/lattice/core/next.py +86 -0
  74. lattice_tracker-0.1.0/src/lattice/core/relationships.py +56 -0
  75. lattice_tracker-0.1.0/src/lattice/core/stats.py +225 -0
  76. lattice_tracker-0.1.0/src/lattice/core/tasks.py +250 -0
  77. lattice_tracker-0.1.0/src/lattice/dashboard/__init__.py +1 -0
  78. lattice_tracker-0.1.0/src/lattice/dashboard/server.py +1257 -0
  79. lattice_tracker-0.1.0/src/lattice/dashboard/static/.gitkeep +0 -0
  80. lattice_tracker-0.1.0/src/lattice/dashboard/static/index.html +5199 -0
  81. lattice_tracker-0.1.0/src/lattice/mcp/__init__.py +0 -0
  82. lattice_tracker-0.1.0/src/lattice/mcp/resources.py +150 -0
  83. lattice_tracker-0.1.0/src/lattice/mcp/server.py +24 -0
  84. lattice_tracker-0.1.0/src/lattice/mcp/tools.py +975 -0
  85. lattice_tracker-0.1.0/src/lattice/plugins.py +122 -0
  86. lattice_tracker-0.1.0/src/lattice/storage/__init__.py +1 -0
  87. lattice_tracker-0.1.0/src/lattice/storage/fs.py +155 -0
  88. lattice_tracker-0.1.0/src/lattice/storage/hooks.py +74 -0
  89. lattice_tracker-0.1.0/src/lattice/storage/locks.py +78 -0
  90. lattice_tracker-0.1.0/src/lattice/storage/operations.py +100 -0
  91. lattice_tracker-0.1.0/src/lattice/storage/short_ids.py +122 -0
  92. lattice_tracker-0.1.0/src/lattice/templates/__init__.py +0 -0
  93. lattice_tracker-0.1.0/src/lattice/templates/claude_md_block.py +96 -0
  94. lattice_tracker-0.1.0/tests/__init__.py +0 -0
  95. lattice_tracker-0.1.0/tests/conftest.py +90 -0
  96. lattice_tracker-0.1.0/tests/test_cli/__init__.py +0 -0
  97. lattice_tracker-0.1.0/tests/test_cli/test_archive_cmds.py +369 -0
  98. lattice_tracker-0.1.0/tests/test_cli/test_artifact_cmds.py +568 -0
  99. lattice_tracker-0.1.0/tests/test_cli/test_edge_cases.py +340 -0
  100. lattice_tracker-0.1.0/tests/test_cli/test_idempotency.py +253 -0
  101. lattice_tracker-0.1.0/tests/test_cli/test_init.py +543 -0
  102. lattice_tracker-0.1.0/tests/test_cli/test_integration.py +425 -0
  103. lattice_tracker-0.1.0/tests/test_cli/test_integrity_cmds.py +391 -0
  104. lattice_tracker-0.1.0/tests/test_cli/test_link_cmds.py +467 -0
  105. lattice_tracker-0.1.0/tests/test_cli/test_next_cmd.py +202 -0
  106. lattice_tracker-0.1.0/tests/test_cli/test_output_formats.py +243 -0
  107. lattice_tracker-0.1.0/tests/test_cli/test_plugins.py +197 -0
  108. lattice_tracker-0.1.0/tests/test_cli/test_query_cmds.py +770 -0
  109. lattice_tracker-0.1.0/tests/test_cli/test_rebuild_determinism.py +267 -0
  110. lattice_tracker-0.1.0/tests/test_cli/test_short_id_integration.py +513 -0
  111. lattice_tracker-0.1.0/tests/test_cli/test_stats_cmds.py +160 -0
  112. lattice_tracker-0.1.0/tests/test_cli/test_task_cmds.py +731 -0
  113. lattice_tracker-0.1.0/tests/test_cli/test_weather_cmds.py +647 -0
  114. lattice_tracker-0.1.0/tests/test_core/__init__.py +0 -0
  115. lattice_tracker-0.1.0/tests/test_core/test_artifacts.py +175 -0
  116. lattice_tracker-0.1.0/tests/test_core/test_config.py +319 -0
  117. lattice_tracker-0.1.0/tests/test_core/test_events.py +329 -0
  118. lattice_tracker-0.1.0/tests/test_core/test_ids.py +188 -0
  119. lattice_tracker-0.1.0/tests/test_core/test_next.py +265 -0
  120. lattice_tracker-0.1.0/tests/test_core/test_plugins.py +212 -0
  121. lattice_tracker-0.1.0/tests/test_core/test_properties.py +300 -0
  122. lattice_tracker-0.1.0/tests/test_core/test_relationships.py +134 -0
  123. lattice_tracker-0.1.0/tests/test_core/test_schema_compat.py +159 -0
  124. lattice_tracker-0.1.0/tests/test_core/test_short_ids.py +122 -0
  125. lattice_tracker-0.1.0/tests/test_core/test_tasks.py +677 -0
  126. lattice_tracker-0.1.0/tests/test_dashboard/__init__.py +1 -0
  127. lattice_tracker-0.1.0/tests/test_dashboard/conftest.py +246 -0
  128. lattice_tracker-0.1.0/tests/test_dashboard/test_graph_api.py +310 -0
  129. lattice_tracker-0.1.0/tests/test_dashboard/test_server.py +1088 -0
  130. lattice_tracker-0.1.0/tests/test_mcp/__init__.py +0 -0
  131. lattice_tracker-0.1.0/tests/test_mcp/conftest.py +34 -0
  132. lattice_tracker-0.1.0/tests/test_mcp/test_resources.py +105 -0
  133. lattice_tracker-0.1.0/tests/test_mcp/test_tools.py +434 -0
  134. lattice_tracker-0.1.0/tests/test_storage/__init__.py +0 -0
  135. lattice_tracker-0.1.0/tests/test_storage/test_concurrency.py +544 -0
  136. lattice_tracker-0.1.0/tests/test_storage/test_crash_recovery.py +398 -0
  137. lattice_tracker-0.1.0/tests/test_storage/test_fs.py +150 -0
  138. lattice_tracker-0.1.0/tests/test_storage/test_hooks.py +369 -0
  139. lattice_tracker-0.1.0/tests/test_storage/test_locks.py +175 -0
  140. lattice_tracker-0.1.0/tests/test_storage/test_operations.py +152 -0
  141. lattice_tracker-0.1.0/tests/test_storage/test_root_discovery.py +96 -0
  142. lattice_tracker-0.1.0/tests/test_storage/test_scale.py +190 -0
  143. lattice_tracker-0.1.0/tests/test_storage/test_short_ids.py +189 -0
  144. lattice_tracker-0.1.0/uv.lock +856 -0
@@ -0,0 +1 @@
1
+ *.jsonl merge=union
@@ -0,0 +1,81 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ concurrency:
14
+ group: ci-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ lint:
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 5
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v4
25
+ - name: Set up Python
26
+ run: uv python install 3.12
27
+ - name: Install dependencies
28
+ run: uv sync --extra dev
29
+ - name: Lint
30
+ run: uv run ruff check src/ tests/
31
+ - name: Format check
32
+ run: uv run ruff format --check src/ tests/
33
+
34
+ test:
35
+ runs-on: ubuntu-latest
36
+ timeout-minutes: 10
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ python-version: ["3.12", "3.13"]
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ - name: Install uv
44
+ uses: astral-sh/setup-uv@v4
45
+ - name: Set up Python ${{ matrix.python-version }}
46
+ run: uv python install ${{ matrix.python-version }}
47
+ - name: Install dependencies
48
+ run: uv sync --extra dev
49
+ - name: Test
50
+ run: uv run pytest -x -q
51
+
52
+ type-check:
53
+ runs-on: ubuntu-latest
54
+ timeout-minutes: 5
55
+ continue-on-error: true # advisory until codebase is fully typed
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+ - name: Install uv
59
+ uses: astral-sh/setup-uv@v4
60
+ - name: Set up Python
61
+ run: uv python install 3.12
62
+ - name: Install dependencies
63
+ run: uv sync --extra dev
64
+ - name: Type check
65
+ run: uv run mypy src/lattice/
66
+
67
+ publish:
68
+ needs: [lint, test]
69
+ runs-on: ubuntu-latest
70
+ if: startsWith(github.ref, 'refs/tags/v')
71
+ permissions:
72
+ contents: read
73
+ id-token: write
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - name: Install uv
77
+ uses: astral-sh/setup-uv@v4
78
+ - name: Build
79
+ run: uv build
80
+ - name: Publish to PyPI
81
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,38 @@
1
+ # Lattice runtime directory (prevent test artifacts in source repo)
2
+ .lattice/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+ *.so
9
+ *.egg-info/
10
+ *.egg
11
+ dist/
12
+ build/
13
+ *.whl
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+
19
+ # Testing
20
+ .pytest_cache/
21
+ htmlcov/
22
+ .coverage
23
+ coverage.xml
24
+
25
+ # Linting
26
+ .ruff_cache/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+ *~
34
+
35
+ # OS
36
+ .DS_Store
37
+ Thumbs.db
38
+ .hypothesis/
@@ -0,0 +1,415 @@
1
+ # Lattice
2
+
3
+ Stage 11 Agentics' file-based, agent-native task tracker with an event-sourced core.
4
+
5
+ ## Work Intake — Mandatory for All New Work in This Project
6
+
7
+ This project coordinates through Lattice. The `.lattice/` directory is the coordination state.
8
+
9
+ When work arrives — a plan, a feature request, a bug, a conversation that implies something needs building — your first action is to give it a name in Lattice. Before you plan. Before you implement. Before you touch a single file. The task must exist in the system before the work begins, because work that isn't tracked is work that other minds cannot see, cannot build on, cannot trust.
10
+
11
+ ```
12
+ lattice create "<title>" --actor agent:<your-id>
13
+ ```
14
+
15
+ This is not bookkeeping. This is the minimum viable act of coordination: declaring that something is happening, and who is doing it.
16
+
17
+ **When to create a task:**
18
+ - New feature, bug fix, refactoring, or cleanup that will produce commits
19
+ - Work that pivots away from what you're currently doing ("actually, let's do X instead")
20
+ - Anything a future mind would benefit from knowing happened
21
+
22
+ **When NOT to create a task (it's a sub-step of existing work):**
23
+ - Follow-up fixes within a task you're already tracking (lint cleanup, test fixes from your feature)
24
+ - Pure research or conversation with no deliverable
25
+ - Work explicitly scoped under an existing LAT-* task
26
+
27
+ When in doubt, create the task. A small task costs nothing. Lost visibility costs everything.
28
+
29
+ ### Status Is a Signal, Not a Chore
30
+
31
+ Every status transition is an event — immutable, attributed, permanent. Lattice is the source of ground truth for what is happening right now.
32
+
33
+ **The cardinal rule: update status BEFORE you start the work, not after.** If you're about to plan a task, move it to `in_planning` first. If you're about to implement, move it to `in_progress` first. If the board says a task is in `backlog` but an agent is actively working on it, the board is lying — and every other mind reading it is making decisions on false information.
34
+
35
+ ```
36
+ lattice status <task> <status> --actor agent:<your-id>
37
+ ```
38
+
39
+ `backlog → in_planning → planned → in_progress → review → done`
40
+
41
+ **Transition discipline:**
42
+ - Moving to `in_planning`? Do it before you open the first file.
43
+ - Moving to `in_progress`? Do it before you write the first line of code.
44
+ - Moving to `review`? Do it when implementation is complete, before review starts.
45
+ - Moving to `done`? Do it when review passes and work is merged/shipped.
46
+ - Spawning a sub-agent to work on a task? Update status in the parent context before the sub-agent launches.
47
+
48
+ ### Actor Attribution
49
+
50
+ Every Lattice operation requires an `--actor`. Attribution follows authorship of the decision, not authorship of the keystroke.
51
+
52
+ | Situation | Actor | Why |
53
+ |-----------|-------|-----|
54
+ | Agent autonomously creates or modifies a task | `agent:<id>` | Agent was the decision-maker |
55
+ | Human creates via direct interaction (UI, manual CLI) | `human:<id>` | Human typed it |
56
+ | Human meaningfully shaped the outcome in conversation with an agent | `human:<id>` | Human authored the decision; agent was the instrument |
57
+ | Agent creates based on its own analysis, unprompted | `agent:<id>` | Agent authored the decision |
58
+
59
+ When in doubt, give the human credit. If the human was substantively involved in shaping *what* a task is — not just saying "go create tasks" but actually defining scope, debating structure, giving feedback — the human is the actor.
60
+
61
+ ### Leave Breadcrumbs
62
+
63
+ You are not the last mind that will touch this work. Use `lattice comment` to record what you tried, what you chose, what you left undone. Use `.lattice/notes/<task_id>.md` for longer-form thinking. The record you leave is the only bridge between your context and theirs.
64
+
65
+ ### Quick Reference
66
+
67
+ ```
68
+ lattice create "<title>" --actor agent:<id>
69
+ lattice status <task> <status> --actor agent:<id>
70
+ lattice assign <task> <actor> --actor agent:<id>
71
+ lattice comment <task> "<text>" --actor agent:<id>
72
+ lattice show <task>
73
+ lattice list
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Disambiguation: "Lattice" the Codebase vs. "Lattice" the Instance
79
+
80
+ This project **dogfoods itself**. There are two distinct things called "Lattice" in this directory:
81
+
82
+ 1. **The Lattice source code** — the Python project under `src/lattice/` that you build, test, and modify. This is what `git` tracks.
83
+ 2. **The `.lattice/` data directory** — a live Lattice instance initialized in this repo for tracking development tasks. This is `.gitignore`d runtime state, not source code.
84
+
85
+ When someone says "is Lattice set up?" they could mean either. Clarify which:
86
+ - **"Is the dev environment set up?"** → Can you run `uv run lattice --help`? Are deps installed?
87
+ - **"Is Lattice tracking tasks here?"** → Does `.lattice/` exist with a `config.json`? (Yes — it's initialized and ready for use.)
88
+
89
+ **Rule:** Never confuse changes to `src/lattice/` (source code) with changes to `.lattice/` (instance data). They are independent. Editing source code does not affect the running instance until you reinstall (`uv pip install -e ".[dev]"`).
90
+
91
+ ## Quick Reference
92
+
93
+ | Item | Value |
94
+ |------|-------|
95
+ | Language | Python 3.12+ |
96
+ | CLI framework | Click |
97
+ | Testing | pytest |
98
+ | Linting | ruff |
99
+ | Package manager | uv |
100
+ | Entry point | `lattice` (via `[project.scripts]`) |
101
+ | On-disk root | `.lattice/` in any project directory |
102
+
103
+ ## Key Documents
104
+
105
+ | Document | Purpose |
106
+ |----------|---------|
107
+ | `ProjectRequirements_v1.md` | Full specification — object model, schemas, CLI commands, invariants |
108
+ | `Decisions.md` | Architectural decisions with rationale (append-only log) |
109
+
110
+ **Read `ProjectRequirements_v1.md` before making any architectural change.** It defines system invariants that must not be violated.
111
+
112
+ ## Architecture
113
+
114
+ ### Core Principle: Events are Authoritative
115
+
116
+ The event log (JSONL) is the source of truth. Task JSON files are materialized snapshots for fast reads. If they disagree, events win. `lattice rebuild` replays events to regenerate snapshots.
117
+
118
+ ### On-Disk Layout (`.lattice/`)
119
+
120
+ ```
121
+ .lattice/
122
+ ├── config.json # Workflow, statuses, transitions, WIP limits, project_code
123
+ ├── ids.json # Derived short ID index (short_id -> ULID mapping + next_seq)
124
+ ├── tasks/<task_id>.json # Materialized task snapshots
125
+ ├── events/<task_id>.jsonl # Per-task event logs (append-only)
126
+ ├── events/_lifecycle.jsonl # Lifecycle event log (derived, rebuildable from per-task logs)
127
+ ├── artifacts/meta/<art_id>.json # Artifact metadata
128
+ ├── artifacts/payload/<art_id>.* # Artifact payloads
129
+ ├── notes/<task_id>.md # Human-editable markdown notes (non-authoritative)
130
+ ├── archive/ # Mirrors tasks/events/notes for archived items
131
+ │ ├── tasks/
132
+ │ ├── events/
133
+ │ └── notes/
134
+ └── locks/ # Internal lock files for concurrency
135
+ ```
136
+
137
+ ### Short IDs
138
+
139
+ Tasks can have human-friendly short IDs (e.g., `LAT-42`) when a `project_code` is configured. Short IDs are aliases — all CLI commands accept both ULID (`task_01...`) and short ID inputs. Resolution happens at the CLI layer via `resolve_task_id()` in `cli/helpers.py`. The `ids.json` index maps short IDs to ULIDs and is derived (rebuildable via `lattice rebuild --all`).
140
+
141
+ ### Write Path
142
+
143
+ The CLI is the **only** write interface for authoritative state. All writes are:
144
+ - **Event-first** (append event, then materialize snapshot — crash between the two is recoverable via `rebuild`)
145
+ - **Lock-protected** (file locks in `.lattice/locks/`)
146
+ - **Atomic** (write temp file, fsync, rename for snapshots; lock + append + flush for events)
147
+
148
+ Multi-lock operations acquire locks in deterministic (sorted) order to prevent deadlocks.
149
+
150
+ Notes (`notes/<task_id>.md`) are an explicit exception — they are non-authoritative supplementary files edited directly by humans or agents.
151
+
152
+ ### Root Discovery
153
+
154
+ The CLI finds `.lattice/` by walking up from cwd (like `git` finds `.git/`). Override with `LATTICE_ROOT` env var. Commands other than `lattice init` error if no `.lattice/` is found.
155
+
156
+ ### Identifiers
157
+
158
+ All entities use ULIDs with type prefixes:
159
+ - `task_01HQ...` — tasks
160
+ - `ev_01HQ...` — events
161
+ - `art_01HQ...` — artifacts
162
+
163
+ IDs are stable and never change. The CLI supports `--id` for caller-supplied IDs (idempotent retries). Same ID + same payload = success. Same ID + different payload = conflict error.
164
+
165
+ ### Actor IDs
166
+
167
+ Free-form `prefix:identifier` strings. No registry in v0.
168
+ - `agent:claude-opus-4`, `agent:codex`, `agent:session-abc123`
169
+ - `human:atin`, `human:joe`
170
+ - `team:frontend`
171
+
172
+ Validation: format only (must have prefix + colon + non-empty id).
173
+
174
+ ## Project Structure
175
+
176
+ ```
177
+ lattice/
178
+ ├── CLAUDE.md
179
+ ├── Decisions.md
180
+ ├── ProjectRequirements_v1.md
181
+ ├── pyproject.toml
182
+ ├── src/
183
+ │ └── lattice/
184
+ │ ├── __init__.py
185
+ │ ├── cli/ # Click command groups
186
+ │ │ ├── __init__.py
187
+ │ │ └── main.py # CLI entry point
188
+ │ ├── core/ # Business logic (no I/O assumptions)
189
+ │ │ ├── __init__.py
190
+ │ │ ├── config.py # Config loading and validation
191
+ │ │ ├── events.py # Event creation, schema, types
192
+ │ │ ├── tasks.py # Task CRUD, snapshot materialization
193
+ │ │ ├── artifacts.py # Artifact metadata and linkage
194
+ │ │ ├── relationships.py # Relationship types and validation
195
+ │ │ └── ids.py # ULID generation and validation
196
+ │ ├── storage/ # Filesystem operations
197
+ │ │ ├── __init__.py
198
+ │ │ ├── fs.py # Atomic writes, directory management
199
+ │ │ └── locks.py # File locking, deterministic ordering
200
+ │ └── dashboard/ # Read-only local web UI
201
+ │ ├── __init__.py
202
+ │ ├── server.py # HTTP server (stdlib)
203
+ │ └── static/ # Single HTML/JS page (no build step)
204
+ └── tests/
205
+ ├── conftest.py # Shared fixtures (tmp .lattice/ dirs, etc.)
206
+ ├── test_cli/
207
+ ├── test_core/
208
+ └── test_storage/
209
+ ```
210
+
211
+ ### Layer Boundaries
212
+
213
+ - **`core/`** contains pure business logic. No filesystem calls. Receives and returns data structures.
214
+ - **`storage/`** handles all filesystem I/O. Atomic writes, locking, directory traversal.
215
+ - **`cli/`** wires core + storage together via Click commands. Handles output formatting.
216
+ - **`dashboard/`** is read-only. Reads `.lattice/` files, serves JSON endpoints + static HTML.
217
+
218
+ This separation exists so that `core/` can be tested without touching the filesystem, and `storage/` can be tested with temp directories.
219
+
220
+ ## Development Setup
221
+
222
+ ```bash
223
+ # Clone and enter
224
+ cd lattice
225
+
226
+ # Create venv and install in dev mode
227
+ uv venv
228
+ uv pip install -e ".[dev]"
229
+
230
+ # Run tests
231
+ uv run pytest
232
+
233
+ # Run linter
234
+ uv run ruff check src/ tests/
235
+ uv run ruff format src/ tests/
236
+
237
+ # Run the CLI
238
+ uv run lattice --help
239
+ ```
240
+
241
+ ## Dependencies
242
+
243
+ ### Runtime
244
+ - `click` — CLI framework
245
+ - `python-ulid` — ULID generation
246
+ - `filelock` — Cross-platform file locking
247
+
248
+ ### Dev
249
+ - `pytest` — testing
250
+ - `ruff` — linting and formatting
251
+
252
+ Minimize dependencies. The dashboard uses only stdlib (`http.server`, `json`). Do not add dependencies without justification.
253
+
254
+ ## Coding Conventions
255
+
256
+ ### JSON Output
257
+
258
+ All JSON written to `.lattice/` must be:
259
+ - Sorted keys
260
+ - 2-space indentation
261
+ - Trailing newline
262
+ - Deterministic (for clean git diffs)
263
+
264
+ ```python
265
+ json.dumps(data, sort_keys=True, indent=2) + "\n"
266
+ ```
267
+
268
+ ### Event Appends
269
+
270
+ Events are single JSONL lines. Append with lock held, flush immediately.
271
+
272
+ ```python
273
+ json.dumps(event, sort_keys=True, separators=(",", ":")) + "\n"
274
+ ```
275
+
276
+ Note: JSONL uses compact separators (no spaces) to keep lines short.
277
+
278
+ ### Error Handling
279
+
280
+ - CLI commands should print human-readable errors to stderr and exit with non-zero codes.
281
+ - `--json` mode uses a structured envelope: `{"ok": true, "data": ...}` or `{"ok": false, "error": {"code": "...", "message": "..."}}`.
282
+ - Never silently swallow errors. If a write fails, the user must know.
283
+
284
+ ### Testing
285
+
286
+ - Every CLI command gets integration tests (invoke Click commands, check `.lattice/` state).
287
+ - Every core module gets unit tests (pure logic, no filesystem).
288
+ - Storage gets tests with real temp directories.
289
+ - Use `tmp_path` fixture for isolated `.lattice/` directories in tests.
290
+
291
+ Critical test categories (add as features land):
292
+ - **Concurrent write safety:** Multiple threads/processes writing to the same task simultaneously must not corrupt files.
293
+ - **Crash recovery:** Simulate crash between event-write and snapshot-write; verify `rebuild` recovers correctly.
294
+ - **Rebuild determinism:** `rebuild` from events must produce byte-identical snapshots regardless of run order.
295
+ - **Idempotency conflicts:** Same ID with different payload must error, not silently overwrite.
296
+
297
+ ## Where Things Live
298
+
299
+ - **Task plans, working docs** → `.lattice/notes/<task_id>.md` — tied to the task, lives where Lattice expects it. This is the default home for any document associated with a specific task (implementation plans, spike findings, etc.).
300
+ - **Repo-level `notes/`** — code reviews, retrospectives, and working documents NOT tied to a specific task.
301
+ - **Repo-level `docs/`** — user-facing documentation: guides, integration docs, getting-started material. Things an end user or adopter would read.
302
+ - **Repo-level `prompts/`** — prompt templates and outstanding implementation checklists. Reusable inputs for agent workflows.
303
+ - **Repo-level `research/`** — external research, competitive analysis, pattern studies, and reference material gathered from outside the project. Things we've learned from others that inform our design.
304
+ - **Don't duplicate** — a document should live in one place, not across multiple folders.
305
+
306
+ ## Workflow Reminders
307
+
308
+ - **Branch naming:** `feat/`, `fix/`, `refactor/`, `test/`, `chore/` prefixes
309
+ - **Commits:** Conventional commit messages (`feat:`, `fix:`, etc.)
310
+ - **Before merging:** All tests pass, ruff clean, no regressions
311
+ - **New decisions:** Append to `Decisions.md` with date, decision, rationale, consequence
312
+ - **Schema changes:** Bump `schema_version`, maintain forward compatibility (unknown fields tolerated)
313
+
314
+ ## What Not to Build (v0)
315
+
316
+ Refer to `ProjectRequirements_v1.md` for full non-goals. Key reminders:
317
+ - No agent registry (actor IDs are free-form strings)
318
+ - No `lattice note` command (notes are direct file edits)
319
+ - ~~No `lattice unarchive`~~ — `lattice unarchive` is now implemented
320
+ - No database or index (filesystem scanning is sufficient at v0 scale)
321
+ - No real-time dashboard updates
322
+ - No authentication or multi-user access control
323
+ - No CI/CD integration, alerting, or process management
324
+
325
+ ## Lattice
326
+
327
+ This project coordinates through Lattice — file-based, event-sourced task tracking built for minds that think in tokens and act in tool calls. The `.lattice/` directory is the coordination state. It lives here, alongside the code, not behind an API or inside someone else's database.
328
+
329
+ ### The First Act
330
+
331
+ When work arrives — a plan, a feature request, a bug, a conversation that implies something needs building — your first action is to give it a name in Lattice. Before you plan. Before you implement. Before you touch a single file. The task must exist in the system before the work begins, because work that isn't tracked is work that other minds cannot see, cannot build on, cannot trust.
332
+
333
+ ```
334
+ lattice create "<title>" --actor agent:<your-id>
335
+ ```
336
+
337
+ This is not bookkeeping. This is the minimum viable act of coordination: declaring that something is happening, and who is doing it.
338
+
339
+ ### Status Is a Signal, Not a Chore
340
+
341
+ Every status transition is an event — immutable, attributed, permanent. When you move a task, you are writing history that future minds will read to understand what happened here. Update status at every real transition:
342
+
343
+ ```
344
+ lattice status <task> <status> --actor agent:<your-id>
345
+ ```
346
+
347
+ ```
348
+ backlog → in_planning → planned → in_progress → review → done
349
+ ↕ ↕
350
+ blocked needs_human
351
+ ```
352
+
353
+ ### When You're Stuck
354
+
355
+ If you hit a point where you need human decision, approval, or input — **signal it immediately** with `needs_human`. This is different from `blocked` (generic external dependency). `needs_human` creates a clear queue of "things waiting on the human."
356
+
357
+ ```
358
+ lattice status <task> needs_human --actor agent:<your-id>
359
+ lattice comment <task> "Need: <what you need, in one line>" --actor agent:<your-id>
360
+ ```
361
+
362
+ **When to use `needs_human`:**
363
+ - Design decisions that require human judgment
364
+ - Missing access, credentials, or permissions
365
+ - Ambiguous requirements that can't be resolved from context
366
+ - Approval needed before proceeding (deploy, merge, etc.)
367
+
368
+ The comment is mandatory — explain what you need in seconds, not minutes. The human's queue should be scannable.
369
+
370
+ ### Actor Attribution
371
+
372
+ Every Lattice operation requires an `--actor`. Attribution follows authorship of the decision, not authorship of the keystroke.
373
+
374
+ | Situation | Actor | Why |
375
+ |-----------|-------|-----|
376
+ | Agent autonomously creates or modifies a task | `agent:<id>` | Agent was the decision-maker |
377
+ | Human creates via direct interaction (UI, manual CLI) | `human:<id>` | Human typed it |
378
+ | Human meaningfully shaped the outcome in conversation with an agent | `human:<id>` | Human authored the decision; agent was the instrument |
379
+ | Agent creates based on its own analysis, unprompted | `agent:<id>` | Agent authored the decision |
380
+
381
+ When in doubt, give the human credit. If the human was substantively involved in shaping *what* a task is — not just saying "go create tasks" but actually defining scope, debating structure, giving feedback — the human is the actor.
382
+
383
+ Users may have their own preferences about attribution. If a user seems frustrated or particular about actor assignments, ask them directly: "How do you want attribution to work? Should I default to crediting you, myself, or ask each time?" Respect whatever norm they set.
384
+
385
+ ### Leave Breadcrumbs
386
+
387
+ You are not the last mind that will touch this work. Use `lattice comment` to record what you tried, what you chose, what you left undone. Use `.lattice/notes/<task_id>.md` for longer-form thinking. The agent that picks up where you left off has no hallway to find you in, no Slack channel to ask. The record you leave is the only bridge between your context and theirs.
388
+
389
+ ### Quick Reference
390
+
391
+ ```
392
+ lattice create "<title>" --actor agent:<id>
393
+ lattice status <task> <status> --actor agent:<id>
394
+ lattice assign <task> <actor> --actor agent:<id>
395
+ lattice comment <task> "<text>" --actor agent:<id>
396
+ lattice next [--actor agent:<id>] [--claim]
397
+ lattice show <task>
398
+ lattice list
399
+ ```
400
+
401
+ ## Lattice -- Stage 11 Workflow
402
+
403
+ This instance follows the Stage 11 Agentics workflow conventions.
404
+
405
+ ### Entrance Interview
406
+
407
+ New projects should begin with the Entrance Interview (`/entrance-interview`) —
408
+ a guided conversation that auto-generates project structure, task graphs, and
409
+ coordination primitives from your goals and technical context.
410
+
411
+ ### Conventions
412
+
413
+ - Actor format: `agent:<model-name>` or `human:<name>`
414
+ - Auto-commit and auto-push on feature branches
415
+ - Lattice tasks are the coordination primitive — all work is tracked