djournal 0.1.0 → 0.3.0
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.
- package/.agents/adapters/shared/journal-hook.js +94 -11
- package/.agents/rules/AUTOMATION.md +2 -2
- package/.agents/rules/FEAT.md +9 -9
- package/.agents/rules/METADATA.md +2 -1
- package/.agents/rules/STATE.md +18 -5
- package/.agents/skills/audit/SKILL.md +4 -2
- package/.agents/skills/init-work/SKILL.md +6 -5
- package/.agents/skills/journal/SKILL.md +3 -2
- package/.agents/skills/plan/SKILL.md +3 -2
- package/.agents/skills/recall/SKILL.md +5 -3
- package/.agents/skills/resume/SKILL.md +2 -1
- package/.agents/skills/switch/SKILL.md +6 -5
- package/.claude/settings.json +4 -2
- package/AGENTS.md +4 -2
- package/README.md +156 -59
- package/bin/journal.js +31 -2
- package/docs/architecture.md +175 -0
- package/docs/djournal-in-practice.md +246 -0
- package/docs/installation.md +152 -0
- package/docs/remote-sync.md +144 -0
- package/docs/uninstalling.md +78 -0
- package/docs/visibility-and-sharing.md +98 -0
- package/lib/installer/index.js +485 -13
- package/lib/installer/merge.js +74 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,26 +1,67 @@
|
|
|
1
1
|
# djournal
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Portable project memory for coding agents, readable by humans.
|
|
4
4
|
|
|
5
|
-
djournal records the path of the work
|
|
6
|
-
next steps
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
djournal records the reasoning path of the work: plans, research, decisions,
|
|
6
|
+
changes, validation, and next steps. It lets you start in Codex, continue in
|
|
7
|
+
Claude Code, switch models, survive context compaction, and still reload the
|
|
8
|
+
same project state from plain Markdown.
|
|
9
|
+
|
|
10
|
+
Code preserves what exists. djournal preserves why it exists.
|
|
9
11
|
|
|
10
12
|
> **Files are memory. Indexes are projections.**
|
|
11
13
|
|
|
12
14
|
## Why djournal exists
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
djournal is built for product and engineering work that moves across sessions,
|
|
17
|
+
models, people, and tools.
|
|
18
|
+
|
|
19
|
+
### Continue across tools
|
|
20
|
+
|
|
21
|
+
Long coding sessions do not survive tool boundaries well when the only handoff
|
|
22
|
+
format is a transcript. A useful session may start in Codex, continue in Claude
|
|
23
|
+
Code, and later resume somewhere else. The journal is the portable handoff
|
|
24
|
+
layer: each agent can read the same Markdown spine, follow the same decisions
|
|
25
|
+
and research links, and close its work in the same structure.
|
|
26
|
+
|
|
27
|
+
The memory belongs to the project, not to a chat session, model, harness,
|
|
28
|
+
database, or proprietary service.
|
|
29
|
+
|
|
30
|
+
### Preserve the reasoning code cannot show
|
|
31
|
+
|
|
32
|
+
Code shows what a system does. It rarely shows why it became that way, what was
|
|
33
|
+
tried, which constraints mattered, which options were rejected, or what should
|
|
34
|
+
happen next.
|
|
35
|
+
|
|
36
|
+
Chat history preserves too much, with weak structure and poor portability.
|
|
37
|
+
Conventional documentation usually captures polished outcomes after the fact.
|
|
38
|
+
Static analysis can inspect the code as it is, but it cannot reliably recover
|
|
39
|
+
the historical decisions that shaped it.
|
|
40
|
+
|
|
41
|
+
djournal records that missing layer while the work happens.
|
|
42
|
+
|
|
43
|
+
### Share institutional knowledge
|
|
44
|
+
|
|
45
|
+
In AI-accelerated teams, traditional documentation can become stale almost as
|
|
46
|
+
soon as it is written. Product specs, implementation notes, and architectural
|
|
47
|
+
rationale need to be produced as a by-product of product and engineering work,
|
|
48
|
+
not as a separate ritual.
|
|
49
|
+
|
|
50
|
+
djournal gives that by-product a durable shape. The same entries that let an
|
|
51
|
+
agent resume work also become institutional knowledge: reviewable by humans,
|
|
52
|
+
searchable with ordinary tools, versioned through Git, and recallable by
|
|
53
|
+
whichever model or harness the team uses next.
|
|
54
|
+
|
|
55
|
+
### Let memory compound
|
|
16
56
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
57
|
+
A journal can start from nothing. The first entries are mostly orientation:
|
|
58
|
+
current state, open questions, and next steps. As the work accumulates, resume
|
|
59
|
+
behavior changes. The agent is no longer guessing from a cold codebase or
|
|
60
|
+
wandering through broad exploration. It reloads a shaped history: what mattered
|
|
61
|
+
before, what was decided, what remains unresolved, and where the next useful
|
|
62
|
+
move probably is.
|
|
20
63
|
|
|
21
|
-
|
|
22
|
-
context when work becomes meaningful; optional hooks make the workflow
|
|
23
|
-
default-on without writing entries behind the agent's back.
|
|
64
|
+
The journal turns past work into focused guidance.
|
|
24
65
|
|
|
25
66
|
## Manifesto
|
|
26
67
|
|
|
@@ -33,42 +74,10 @@ default-on without writing entries behind the agent's back.
|
|
|
33
74
|
4. **Structure should be sufficient, not maximal.** YAML carries stable
|
|
34
75
|
metadata; Markdown carries meaning; links carry relationships.
|
|
35
76
|
5. **Tools should remain replaceable.** Memory must survive changes in models,
|
|
36
|
-
agent harnesses, databases, and
|
|
77
|
+
agent harnesses, databases, vendors, and retrieval systems.
|
|
37
78
|
6. **The workflow should carry the burden.** Maintaining memory should be a
|
|
38
79
|
consequence of meaningful work, not another ritual to remember.
|
|
39
80
|
|
|
40
|
-
## Why plain Markdown
|
|
41
|
-
|
|
42
|
-
Markdown is immediately useful. It can be read before an ingestion pipeline
|
|
43
|
-
runs, searched with ordinary tools, loaded selectively, reviewed line by line,
|
|
44
|
-
and versioned with Git. Frontmatter makes important fields deterministic while
|
|
45
|
-
links turn the directory into an explicit graph.
|
|
46
|
-
|
|
47
|
-
Google Cloud's draft [Open Knowledge Format](https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing/)
|
|
48
|
-
formalizes the same broad pattern: knowledge as linked Markdown with YAML
|
|
49
|
-
frontmatter, portable through Git and independent of the tools that produce or
|
|
50
|
-
consume it. djournal is conceptually aligned with that direction, but uses a
|
|
51
|
-
domain-specific schema for project history and is not currently
|
|
52
|
-
[OKF v0.1](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
|
|
53
|
-
conformant.
|
|
54
|
-
|
|
55
|
-
## Why not only RAG or a knowledge graph?
|
|
56
|
-
|
|
57
|
-
RAG, embeddings, full-text indexes, and graph views are useful retrieval tools.
|
|
58
|
-
They are not ideal as the only durable copy of project memory.
|
|
59
|
-
|
|
60
|
-
| Layer | What it provides |
|
|
61
|
-
| --- | --- |
|
|
62
|
-
| djournal Markdown | Canonical meaning, provenance, chronology, and links |
|
|
63
|
-
| Git | Review, attribution, history, and team exchange |
|
|
64
|
-
| Embeddings / RAG | Semantic retrieval over larger corpora |
|
|
65
|
-
| Graph projection | Traversal, visualization, and multi-hop retrieval |
|
|
66
|
-
|
|
67
|
-
Vector and graph indexes are derived representations: they require ingestion,
|
|
68
|
-
can become stale, and may change with the model or extraction pipeline. djournal
|
|
69
|
-
keeps the authored source inspectable and lets those indexes be rebuilt when
|
|
70
|
-
needed. It complements retrieval infrastructure rather than replacing it.
|
|
71
|
-
|
|
72
81
|
## What djournal records
|
|
73
82
|
|
|
74
83
|
```text
|
|
@@ -85,6 +94,8 @@ needed. It complements retrieval infrastructure rather than replacing it.
|
|
|
85
94
|
Entries carry structured frontmatter, stable identities, summaries, timestamps,
|
|
86
95
|
and typed links. Markdown remains the source of truth.
|
|
87
96
|
|
|
97
|
+
See [spec.md](spec.md) for the complete data model and workflow contracts.
|
|
98
|
+
|
|
88
99
|
## How it works
|
|
89
100
|
|
|
90
101
|
```mermaid
|
|
@@ -105,48 +116,125 @@ flowchart LR
|
|
|
105
116
|
- Hooks never create or modify semantic journal entries.
|
|
106
117
|
- Read-only and trivial requests do not generate unnecessary ceremony.
|
|
107
118
|
|
|
119
|
+
## Why plain Markdown and Git
|
|
120
|
+
|
|
121
|
+
Markdown is immediately useful. It can be read before an ingestion pipeline
|
|
122
|
+
runs, searched with ordinary tools, loaded selectively, reviewed line by line,
|
|
123
|
+
and versioned with Git. Frontmatter makes important fields deterministic while
|
|
124
|
+
links turn the directory into an explicit graph.
|
|
125
|
+
|
|
126
|
+
Git already distributes code history. djournal lets teams preserve reasoning
|
|
127
|
+
history in the same reviewable medium: who changed the memory, when it changed,
|
|
128
|
+
what it referenced, and how it evolved. That makes institutional knowledge easy
|
|
129
|
+
for people to inspect and easy for agents to recall.
|
|
130
|
+
|
|
131
|
+
Google Cloud's draft [Open Knowledge Format](https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing/)
|
|
132
|
+
formalizes the same broad pattern: knowledge as linked Markdown with YAML
|
|
133
|
+
frontmatter, portable through Git and independent of the tools that produce or
|
|
134
|
+
consume it. djournal is conceptually aligned with that direction, but uses a
|
|
135
|
+
domain-specific schema for project history and is not currently
|
|
136
|
+
[OKF v0.1](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
|
|
137
|
+
conformant.
|
|
138
|
+
|
|
139
|
+
## Why not only RAG or a knowledge graph?
|
|
140
|
+
|
|
141
|
+
RAG, embeddings, full-text indexes, and graph views are useful retrieval tools.
|
|
142
|
+
They are not ideal as the only durable copy of project memory.
|
|
143
|
+
|
|
144
|
+
| Layer | What it provides |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| djournal Markdown | Canonical meaning, provenance, chronology, and links |
|
|
147
|
+
| Git | Review, attribution, history, and team exchange |
|
|
148
|
+
| Embeddings / RAG | Semantic retrieval over larger corpora |
|
|
149
|
+
| Graph projection | Traversal, visualization, and multi-hop retrieval |
|
|
150
|
+
|
|
151
|
+
Vector and graph indexes are derived representations: they require ingestion,
|
|
152
|
+
can become stale, and may change with the model or extraction pipeline. djournal
|
|
153
|
+
keeps the authored source inspectable and lets those indexes be rebuilt when
|
|
154
|
+
needed. It complements retrieval infrastructure rather than replacing it.
|
|
155
|
+
|
|
156
|
+
Large context windows help, but they do not replace authored memory. A million
|
|
157
|
+
tokens can hold more text; the agent still needs to know what matters.
|
|
158
|
+
|
|
108
159
|
## Install
|
|
109
160
|
|
|
110
161
|
Requires Node.js 18 or newer. Run this from the project you want to equip:
|
|
111
162
|
|
|
112
163
|
```bash
|
|
113
|
-
|
|
164
|
+
npm install -g djournal
|
|
165
|
+
djournal install
|
|
114
166
|
```
|
|
115
167
|
|
|
116
|
-
The
|
|
117
|
-
|
|
168
|
+
The global install gives you the `djournal` and `journal` commands. The
|
|
169
|
+
installer targets the current directory and detects Codex or Claude Code. Select
|
|
170
|
+
explicitly when needed:
|
|
118
171
|
|
|
119
172
|
```bash
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
173
|
+
djournal install --harness codex
|
|
174
|
+
djournal install --harness claude-code
|
|
175
|
+
djournal install --all
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
If you do not want a global install, use `npx`:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
npx djournal install
|
|
123
182
|
```
|
|
124
183
|
|
|
125
184
|
Then use your coding agent normally.
|
|
126
185
|
|
|
186
|
+
Install creates a local project marker (`.djournal.json`) and a canonical
|
|
187
|
+
per-project store under `~/.djournal/projects/<project-key>/`:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
~/.djournal/projects/<project-key>/
|
|
191
|
+
config.json
|
|
192
|
+
.journal/
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The project store is the private write target. A repository `.journal/` or
|
|
196
|
+
standalone journal repo is a projection that receives shared work only after
|
|
197
|
+
you opt in.
|
|
198
|
+
|
|
199
|
+
For Claude Code, install also grants the project access to that exact global
|
|
200
|
+
store path in `.claude/settings.json`, plus the safe `journal`/`djournal`
|
|
201
|
+
commands used by the workflow. Codex uses runtime sandbox configuration for
|
|
202
|
+
filesystem access, so sandboxed Codex sessions must include the generated store
|
|
203
|
+
path when they need canonical journal memory.
|
|
204
|
+
|
|
127
205
|
## Lifecycle
|
|
128
206
|
|
|
129
207
|
```bash
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
208
|
+
djournal status
|
|
209
|
+
djournal doctor
|
|
210
|
+
djournal config sync.enabled true
|
|
211
|
+
djournal share --all
|
|
212
|
+
djournal share
|
|
213
|
+
djournal sync
|
|
214
|
+
djournal upgrade
|
|
215
|
+
djournal uninstall
|
|
134
216
|
```
|
|
135
217
|
|
|
136
218
|
Installation preserves existing agent configuration. Uninstallation removes
|
|
137
|
-
djournal's tooling while retaining
|
|
138
|
-
revived later.
|
|
219
|
+
djournal's tooling while retaining durable project memory and the project
|
|
220
|
+
marker so the journal can be revived later.
|
|
139
221
|
|
|
140
222
|
Existing `AGENTS.md` and `CLAUDE.md` files are never replaced. djournal adds an
|
|
141
223
|
owned block, updates only that block, and removes only that block during
|
|
142
224
|
uninstall; surrounding project instructions remain untouched.
|
|
143
225
|
|
|
144
|
-
|
|
226
|
+
`share` marks the active work item in the global sharing index. `sync` is
|
|
227
|
+
opt-in; in colocated mode it projects shared work into the product repository
|
|
228
|
+
for normal commits, and in standalone mode it projects shared work into a
|
|
229
|
+
dedicated journal repository.
|
|
145
230
|
|
|
146
231
|
## Status
|
|
147
232
|
|
|
148
233
|
Codex and Claude Code are supported. OpenCode, Pi, and Zed adapters are planned.
|
|
149
234
|
|
|
235
|
+
Git-backed sharing and automatic sync are opt-in so local-only work remains
|
|
236
|
+
private by default.
|
|
237
|
+
|
|
150
238
|
## Contributing and releases
|
|
151
239
|
|
|
152
240
|
Pull request titles use Conventional Commit form, such as
|
|
@@ -156,3 +244,12 @@ Pull request titles use Conventional Commit form, such as
|
|
|
156
244
|
increment the major version.
|
|
157
245
|
|
|
158
246
|
djournal is licensed under the [Apache License 2.0](LICENSE).
|
|
247
|
+
|
|
248
|
+
## Documentation
|
|
249
|
+
|
|
250
|
+
- [Installation and repository layouts](docs/installation.md)
|
|
251
|
+
- [Remote Git sync setup](docs/remote-sync.md)
|
|
252
|
+
- [Architecture and data model](docs/architecture.md)
|
|
253
|
+
- [Visibility and sharing](docs/visibility-and-sharing.md)
|
|
254
|
+
- [Djournal in practice](docs/djournal-in-practice.md)
|
|
255
|
+
- [Uninstalling and reinstalling](docs/uninstalling.md)
|
package/bin/journal.js
CHANGED
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
const path = require("node:path");
|
|
6
6
|
const {
|
|
7
7
|
InstallerError,
|
|
8
|
+
configure,
|
|
8
9
|
doctor,
|
|
9
10
|
install,
|
|
11
|
+
share,
|
|
12
|
+
sync,
|
|
10
13
|
status,
|
|
11
14
|
uninstall,
|
|
12
15
|
upgrade,
|
|
@@ -21,13 +24,17 @@ function usage() {
|
|
|
21
24
|
journal uninstall [--target DIR] [--harness LIST | --all]
|
|
22
25
|
journal status [--target DIR] [--json]
|
|
23
26
|
journal doctor [--target DIR] [--json]
|
|
27
|
+
journal config [--target DIR] [KEY [VALUE]] [--dry-run] [--json]
|
|
28
|
+
journal share [--target DIR] [--work SLUG | --all] [--dry-run] [--json]
|
|
29
|
+
journal sync [--target DIR] [--work SLUG] [--dry-run] [--json]
|
|
24
30
|
|
|
25
31
|
Options:
|
|
26
32
|
--dry-run Show the planned operation without writing
|
|
27
33
|
--yes Disable interactive harness selection
|
|
28
34
|
--json Emit JSON
|
|
35
|
+
--work SLUG Select a journal work item instead of active state
|
|
29
36
|
--harness LIST Comma-separated codex,claude-code selection
|
|
30
|
-
--all Select or
|
|
37
|
+
--all Select all work items for share, or every harness
|
|
31
38
|
--instructions-only Install core instructions without harness hooks
|
|
32
39
|
`;
|
|
33
40
|
}
|
|
@@ -35,7 +42,7 @@ Options:
|
|
|
35
42
|
function parseArgs(argv) {
|
|
36
43
|
const args = [...argv];
|
|
37
44
|
const command = args.shift();
|
|
38
|
-
if (!command || !["install", "upgrade", "uninstall", "status", "doctor"].includes(command)) {
|
|
45
|
+
if (!command || !["install", "upgrade", "uninstall", "status", "doctor", "config", "share", "sync"].includes(command)) {
|
|
39
46
|
throw new InstallerError(usage(), "USAGE");
|
|
40
47
|
}
|
|
41
48
|
const options = { command, harnesses: [] };
|
|
@@ -45,6 +52,10 @@ function parseArgs(argv) {
|
|
|
45
52
|
if (!args.length) throw new InstallerError("--target requires a value", "USAGE");
|
|
46
53
|
options.target = args.shift();
|
|
47
54
|
} else if (arg.startsWith("--target=")) options.target = arg.slice(9);
|
|
55
|
+
else if (arg === "--work") {
|
|
56
|
+
if (!args.length) throw new InstallerError("--work requires a value", "USAGE");
|
|
57
|
+
options.work = args.shift();
|
|
58
|
+
} else if (arg.startsWith("--work=")) options.work = arg.slice(7);
|
|
48
59
|
else if (arg === "--harness") {
|
|
49
60
|
if (!args.length) throw new InstallerError("--harness requires a value", "USAGE");
|
|
50
61
|
options.harnesses.push(...args.shift().split(",").filter(Boolean));
|
|
@@ -52,12 +63,19 @@ function parseArgs(argv) {
|
|
|
52
63
|
else if (arg === "--all") options.all = true;
|
|
53
64
|
else if (arg === "--instructions-only") options.instructionsOnly = true;
|
|
54
65
|
else if (arg === "--dry-run") options.dryRun = true;
|
|
66
|
+
else if (arg === "--auto") options.auto = true;
|
|
55
67
|
else if (arg === "--yes") options.yes = true;
|
|
56
68
|
else if (arg === "--json") options.json = true;
|
|
57
69
|
else if (arg === "--help" || arg === "-h") throw new InstallerError(usage(), "HELP");
|
|
70
|
+
else if (command === "config" && !options.key) options.key = arg;
|
|
71
|
+
else if (command === "config" && typeof options.value === "undefined") options.value = arg;
|
|
58
72
|
else throw new InstallerError(`unknown option: ${arg}`, "USAGE");
|
|
59
73
|
}
|
|
60
74
|
if (options.all && options.harnesses.length) throw new InstallerError("use either --all or --harness", "USAGE");
|
|
75
|
+
if (options.all && options.work) throw new InstallerError("use either --all or --work", "USAGE");
|
|
76
|
+
if (options.all && !["install", "uninstall", "share"].includes(command)) {
|
|
77
|
+
throw new InstallerError(`--all is not supported for ${command}`, "USAGE");
|
|
78
|
+
}
|
|
61
79
|
if (options.instructionsOnly && (options.all || options.harnesses.length)) {
|
|
62
80
|
throw new InstallerError("--instructions-only cannot be combined with harness selection", "USAGE");
|
|
63
81
|
}
|
|
@@ -76,6 +94,14 @@ function print(value, json) {
|
|
|
76
94
|
else if (typeof value.installed === "boolean") process.stdout.write(value.installed ? `installed: ${value.target}\n` : `not installed: ${value.target}\n`);
|
|
77
95
|
else process.stdout.write(`${value.ok ? "ok" : "failed"}: ${value.target}\n`);
|
|
78
96
|
if (value.harnesses) process.stdout.write(`harnesses: ${value.harnesses.join(", ") || "instructions-only"}\n`);
|
|
97
|
+
if (value.key) process.stdout.write(`${value.key}: ${JSON.stringify(value.value)}\n`);
|
|
98
|
+
else if (value.config) process.stdout.write(`${JSON.stringify(value.config, null, 2)}\n`);
|
|
99
|
+
if (value.workItems) {
|
|
100
|
+
for (const item of value.workItems) {
|
|
101
|
+
process.stdout.write(`${item.changed ? "shared" : "unchanged"} ${item.work}\n`);
|
|
102
|
+
if (item.warning) process.stdout.write(`warning: ${item.warning}\n`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
79
105
|
if (value.conflicts?.length) process.stdout.write(`conflicts: ${value.conflicts.join(", ")}\n`);
|
|
80
106
|
if (value.files) {
|
|
81
107
|
for (const file of value.files) process.stdout.write(`${file.status.padEnd(8)} ${file.path}\n`);
|
|
@@ -101,6 +127,9 @@ async function main() {
|
|
|
101
127
|
else if (options.command === "upgrade") result = await upgrade(options);
|
|
102
128
|
else if (options.command === "uninstall") result = uninstall(options);
|
|
103
129
|
else if (options.command === "status") result = status(options);
|
|
130
|
+
else if (options.command === "config") result = configure(options);
|
|
131
|
+
else if (options.command === "share") result = share(options);
|
|
132
|
+
else if (options.command === "sync") result = sync(options);
|
|
104
133
|
else result = doctor(options);
|
|
105
134
|
print(result, options.json);
|
|
106
135
|
if (result.ok === false || result.installed === false || result.clean === false || result.conflicts?.length) process.exitCode = 2;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Architecture and Data Model
|
|
2
|
+
|
|
3
|
+
djournal is a filesystem journal. Markdown is the source of truth; indexes,
|
|
4
|
+
RAG systems, graph views, and model context are projections over that source.
|
|
5
|
+
|
|
6
|
+
## Directory layout
|
|
7
|
+
|
|
8
|
+
The canonical journal lives in the user's djournal home, keyed by project:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
~/.djournal/projects/<project-key>/
|
|
12
|
+
config.json
|
|
13
|
+
.journal/
|
|
14
|
+
state.json
|
|
15
|
+
work/<work-item>/
|
|
16
|
+
work.md
|
|
17
|
+
journal/
|
|
18
|
+
decisions/
|
|
19
|
+
docs/
|
|
20
|
+
_research/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The installed project contains a marker that points back to that store:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
.djournal.json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
When sync is enabled, a repository-local `.journal/` is a projection containing
|
|
30
|
+
the shared work items copied out of the global store.
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
<projection-target>/
|
|
34
|
+
.journal/
|
|
35
|
+
work/<shared-work-item>/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Work items
|
|
39
|
+
|
|
40
|
+
A work item is a durable unit of product or engineering work. It may span
|
|
41
|
+
repositories, branches, harnesses, and models.
|
|
42
|
+
|
|
43
|
+
Every work item has:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
~/.djournal/projects/<project-key>/.journal/work/<slug>/work.md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The frontmatter stores stable identity, title, status, visibility, authorship,
|
|
50
|
+
and timestamps.
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
`config.json` is a sibling of the global `.journal/` directory. It stores
|
|
55
|
+
project identity, sync settings, and the sharing index. Sync is disabled unless
|
|
56
|
+
configuration opts in:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"project": {
|
|
61
|
+
"id": "my-product-a1b2c3d4",
|
|
62
|
+
"name": "my-product",
|
|
63
|
+
"sourcePath": "/workspace/my-product"
|
|
64
|
+
},
|
|
65
|
+
"sync": {
|
|
66
|
+
"enabled": true,
|
|
67
|
+
"mode": "colocated",
|
|
68
|
+
"path": "/workspace/my-product",
|
|
69
|
+
"auto": false
|
|
70
|
+
},
|
|
71
|
+
"sharing": {
|
|
72
|
+
"default": "local_only",
|
|
73
|
+
"sharedWorkItems": {}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use the CLI to change it:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
djournal config sync.enabled true
|
|
82
|
+
djournal config sync.mode colocated
|
|
83
|
+
djournal config sync.path /workspace/my-product
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use `mode: "standalone"` for a dedicated journal repository. Use
|
|
87
|
+
`mode: "colocated"` when shared work should be projected into the product
|
|
88
|
+
repository and published by normal product commits.
|
|
89
|
+
|
|
90
|
+
## Entry types
|
|
91
|
+
|
|
92
|
+
| Directory | Entry types | Role |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| `journal/` | `plan`, `implementation`, `status`, `manual` | Spine |
|
|
95
|
+
| `decisions/` | `decision` | Supporting |
|
|
96
|
+
| `docs/` | `doc` | Supporting |
|
|
97
|
+
| `_research/` | `research` | Supporting |
|
|
98
|
+
|
|
99
|
+
The spine is the chronological project timeline. Supporting entries are durable
|
|
100
|
+
evidence and references linked from the spine or from each other.
|
|
101
|
+
|
|
102
|
+
## Frontmatter
|
|
103
|
+
|
|
104
|
+
Entries use YAML frontmatter for stable metadata:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
---
|
|
108
|
+
id: ent_...
|
|
109
|
+
workItemId: wi_...
|
|
110
|
+
entryType: implementation
|
|
111
|
+
entryNumber: 7
|
|
112
|
+
title: Implement README overhaul
|
|
113
|
+
summary: Rewrote README.md around portable project memory.
|
|
114
|
+
createdBy: person@example.com
|
|
115
|
+
createdAt: "2026-07-07T20:03:30.906Z"
|
|
116
|
+
updatedAt: "2026-07-07T20:03:30.906Z"
|
|
117
|
+
source: manual
|
|
118
|
+
---
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The Markdown body carries the human-readable meaning. Frontmatter keeps lookup,
|
|
122
|
+
sorting, identity, and link resolution deterministic.
|
|
123
|
+
|
|
124
|
+
## Links
|
|
125
|
+
|
|
126
|
+
Links are typed objects in frontmatter:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
links:
|
|
130
|
+
- id: lnk_...
|
|
131
|
+
fromEntryId: ent_...
|
|
132
|
+
toEntryId: ent_...
|
|
133
|
+
relation: references
|
|
134
|
+
createdAt: "2026-07-08T08:00:00.000Z"
|
|
135
|
+
targetPath: ../docs/example.md
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Supported relations:
|
|
139
|
+
|
|
140
|
+
- `references`: source uses target as evidence or context
|
|
141
|
+
- `relates_to`: source is loosely connected to target
|
|
142
|
+
- `supersedes`: newer entry replaces or rolls back an older entry
|
|
143
|
+
|
|
144
|
+
## Decisions, docs, and research
|
|
145
|
+
|
|
146
|
+
Decision entries record accepted choices, rationale, consequences, and
|
|
147
|
+
supersession.
|
|
148
|
+
|
|
149
|
+
Doc entries synthesize durable reference material such as architecture notes,
|
|
150
|
+
how-tos, and product explanations.
|
|
151
|
+
|
|
152
|
+
Research entries capture codebase or web findings with sources and open
|
|
153
|
+
questions.
|
|
154
|
+
|
|
155
|
+
## Hooks and skills
|
|
156
|
+
|
|
157
|
+
`AGENTS.md` gives agents portable instructions. Skills perform journal-aware
|
|
158
|
+
work such as resume, planning, research, decision capture, documentation,
|
|
159
|
+
audit, reconciliation, and closure.
|
|
160
|
+
|
|
161
|
+
Hooks remind agents about the workflow and validate final status markers. Hooks
|
|
162
|
+
do not create semantic journal entries. When `.djournal.json` exists, hooks read
|
|
163
|
+
active work and sync config from the global project store.
|
|
164
|
+
|
|
165
|
+
For Claude Code, install also injects a narrow permission grant into
|
|
166
|
+
`.claude/settings.json` for the exact global project store path and safe
|
|
167
|
+
`journal`/`djournal` commands. Codex filesystem access is governed by the Codex
|
|
168
|
+
runtime sandbox, so Codex sessions must be launched with the global store path
|
|
169
|
+
available when sandboxing would otherwise hide `~/.djournal`.
|
|
170
|
+
|
|
171
|
+
## Related docs
|
|
172
|
+
|
|
173
|
+
- [Djournal in practice](djournal-in-practice.md)
|
|
174
|
+
- [Visibility and sharing](visibility-and-sharing.md)
|
|
175
|
+
- [spec.md](../spec.md)
|