docket-agent 0.1.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/LICENSE +21 -0
- package/README.md +268 -0
- package/bin/docket.js +10 -0
- package/eval/REPORT.md +67 -0
- package/eval/run.js +114 -0
- package/eval/scenarios.js +111 -0
- package/package.json +45 -0
- package/spec/SPEC.md +259 -0
- package/src/cli.js +79 -0
- package/src/commands/check.js +41 -0
- package/src/commands/compile.js +45 -0
- package/src/commands/init.js +54 -0
- package/src/commands/list.js +53 -0
- package/src/commands/mcp.js +187 -0
- package/src/commands/new.js +229 -0
- package/src/commands/record.js +116 -0
- package/src/lib/args.js +36 -0
- package/src/lib/compile.js +140 -0
- package/src/lib/loop.js +198 -0
- package/src/lib/pkg.js +5 -0
- package/src/lib/record.js +177 -0
- package/src/lib/ui.js +20 -0
- package/src/lib/warrant.js +142 -0
- package/src/lib/yaml.js +132 -0
- package/templates/client-follow-up.loop.md +59 -0
- package/templates/cross-tool-memory.loop.md +55 -0
- package/templates/insurance-appeal.loop.md +59 -0
- package/templates/marketing-brain.loop.md +62 -0
- package/templates/ticket-handoff.loop.md +59 -0
- package/templates/travel-morning.loop.md +54 -0
- package/templates/weekly-planning.loop.md +55 -0
package/src/lib/yaml.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Minimal YAML subset parser/emitter — enough for loop frontmatter, zero deps.
|
|
2
|
+
//
|
|
3
|
+
// Supported: nested maps, lists of scalars, quoted/unquoted scalars,
|
|
4
|
+
// booleans, null, numbers, `[]` empty lists, `#` comment lines.
|
|
5
|
+
// Deliberately NOT supported: anchors, multi-line scalars, flow maps,
|
|
6
|
+
// lists of maps. Loop files never need them; keeping the grammar small
|
|
7
|
+
// keeps the format auditable.
|
|
8
|
+
|
|
9
|
+
export function parseYaml(text) {
|
|
10
|
+
const lines = [];
|
|
11
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
12
|
+
const trimmed = raw.trim();
|
|
13
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
14
|
+
lines.push({ indent: raw.match(/^ */)[0].length, content: trimmed });
|
|
15
|
+
}
|
|
16
|
+
let i = 0;
|
|
17
|
+
|
|
18
|
+
function parseScalar(s) {
|
|
19
|
+
if (s === 'null' || s === '~') return null;
|
|
20
|
+
if (s === 'true') return true;
|
|
21
|
+
if (s === 'false') return false;
|
|
22
|
+
if (s === '[]') return [];
|
|
23
|
+
if (s === '{}') return {};
|
|
24
|
+
if (/^-?\d+(\.\d+)?$/.test(s)) return Number(s);
|
|
25
|
+
if (s.startsWith('"') && s.endsWith('"') && s.length >= 2) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(s); // unescape \" and \\ — the emitter uses JSON quoting
|
|
28
|
+
} catch {
|
|
29
|
+
return s.slice(1, -1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (s.startsWith("'") && s.endsWith("'") && s.length >= 2) {
|
|
33
|
+
return s.slice(1, -1).replace(/''/g, "'");
|
|
34
|
+
}
|
|
35
|
+
return s;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseBlock(indent) {
|
|
39
|
+
if (i >= lines.length) return null;
|
|
40
|
+
return lines[i].content.startsWith('- ') || lines[i].content === '-'
|
|
41
|
+
? parseList(indent)
|
|
42
|
+
: parseMap(indent);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function parseMap(indent) {
|
|
46
|
+
const obj = {};
|
|
47
|
+
while (i < lines.length) {
|
|
48
|
+
const line = lines[i];
|
|
49
|
+
if (line.indent !== indent || line.content.startsWith('- ')) break;
|
|
50
|
+
const m = line.content.match(/^([^:]+):(.*)$/);
|
|
51
|
+
if (!m) throw new Error(`docket: cannot parse frontmatter line: "${line.content}"`);
|
|
52
|
+
const key = m[1].trim();
|
|
53
|
+
const rest = m[2].trim();
|
|
54
|
+
i++;
|
|
55
|
+
if (rest === '') {
|
|
56
|
+
if (i < lines.length && lines[i].indent > indent) {
|
|
57
|
+
obj[key] = parseBlock(lines[i].indent);
|
|
58
|
+
} else if (
|
|
59
|
+
// Common hand-written style: list items at the same indent as the key.
|
|
60
|
+
i < lines.length &&
|
|
61
|
+
lines[i].indent === indent &&
|
|
62
|
+
(lines[i].content.startsWith('- ') || lines[i].content === '-')
|
|
63
|
+
) {
|
|
64
|
+
obj[key] = parseList(indent);
|
|
65
|
+
} else {
|
|
66
|
+
obj[key] = null;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
obj[key] = parseScalar(rest);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return obj;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function parseList(indent) {
|
|
76
|
+
const arr = [];
|
|
77
|
+
while (i < lines.length) {
|
|
78
|
+
const line = lines[i];
|
|
79
|
+
if (line.indent !== indent || !(line.content.startsWith('- ') || line.content === '-')) break;
|
|
80
|
+
const rest = line.content === '-' ? '' : line.content.slice(2).trim();
|
|
81
|
+
i++;
|
|
82
|
+
arr.push(rest === '' ? null : parseScalar(rest));
|
|
83
|
+
}
|
|
84
|
+
return arr;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const result = parseBlock(0);
|
|
88
|
+
if (i < lines.length) {
|
|
89
|
+
throw new Error(`docket: unexpected indentation near: "${lines[i].content}"`);
|
|
90
|
+
}
|
|
91
|
+
return result ?? {};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function needsQuotes(s) {
|
|
95
|
+
return (
|
|
96
|
+
s === '' ||
|
|
97
|
+
/^[\s#\-?:@&*!|>%'"[\]{}]/.test(s) ||
|
|
98
|
+
/[:#]\s/.test(s) ||
|
|
99
|
+
/\s$/.test(s) ||
|
|
100
|
+
['null', 'true', 'false', '~'].includes(s) ||
|
|
101
|
+
/^-?\d+(\.\d+)?$/.test(s)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function emitScalar(v) {
|
|
106
|
+
if (v === null || v === undefined) return 'null';
|
|
107
|
+
if (typeof v === 'boolean' || typeof v === 'number') return String(v);
|
|
108
|
+
const s = String(v);
|
|
109
|
+
return needsQuotes(s) ? JSON.stringify(s) : s;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function dumpYaml(value, indent = 0) {
|
|
113
|
+
const pad = ' '.repeat(indent);
|
|
114
|
+
if (Array.isArray(value)) {
|
|
115
|
+
if (value.length === 0) return '';
|
|
116
|
+
return value.map((v) => `${pad}- ${emitScalar(v)}`).join('\n') + '\n';
|
|
117
|
+
}
|
|
118
|
+
if (value && typeof value === 'object') {
|
|
119
|
+
let out = '';
|
|
120
|
+
for (const [k, v] of Object.entries(value)) {
|
|
121
|
+
if (Array.isArray(v)) {
|
|
122
|
+
out += v.length === 0 ? `${pad}${k}: []\n` : `${pad}${k}:\n${dumpYaml(v, indent + 2)}`;
|
|
123
|
+
} else if (v && typeof v === 'object') {
|
|
124
|
+
out += `${pad}${k}:\n${dumpYaml(v, indent + 2)}`;
|
|
125
|
+
} else {
|
|
126
|
+
out += `${pad}${k}: ${emitScalar(v)}\n`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
return `${pad}${emitScalar(value)}\n`;
|
|
132
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: client-follow-up
|
|
3
|
+
description: Follow up with a client with the whole history in the room — promises, tone, and the language they already approved.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- account history
|
|
8
|
+
- past email threads with this client
|
|
9
|
+
- meeting notes
|
|
10
|
+
- the contract and current scope
|
|
11
|
+
draft:
|
|
12
|
+
- follow-up email
|
|
13
|
+
- status summary
|
|
14
|
+
- meeting agenda
|
|
15
|
+
change:
|
|
16
|
+
- internal notes on the account
|
|
17
|
+
send: []
|
|
18
|
+
ask:
|
|
19
|
+
- anything the client will see
|
|
20
|
+
- scheduling anything on the client's calendar
|
|
21
|
+
never:
|
|
22
|
+
- unapproved prices, discounts, or scope changes
|
|
23
|
+
- apologizing for things we did not do
|
|
24
|
+
reserved:
|
|
25
|
+
- what gets promised
|
|
26
|
+
- final approval of every outbound message
|
|
27
|
+
- when a relationship problem escalates to a phone call
|
|
28
|
+
record:
|
|
29
|
+
- promises found in the history and whether each is kept, pending, or slipped
|
|
30
|
+
- approved language reused, and any new language that needs sign-off
|
|
31
|
+
- what the draft deliberately does not mention, and why
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Brief
|
|
35
|
+
|
|
36
|
+
- Who this client is: names, roles, who actually decides, who just replies fastest.
|
|
37
|
+
- Every promise made to them, with dates. A follow-up that forgets a promise is worse
|
|
38
|
+
than no follow-up.
|
|
39
|
+
- Approved language vs rejected language. If a phrase was walked back once, it does
|
|
40
|
+
not come back.
|
|
41
|
+
- Their tone preferences: some clients want three bullet points, some want warmth
|
|
42
|
+
first. This client's preference is written here, not guessed each time.
|
|
43
|
+
- Open commercial context: renewal date, expansion talks, any sore spots.
|
|
44
|
+
|
|
45
|
+
# Procedure
|
|
46
|
+
|
|
47
|
+
1. Reconstruct the state of the relationship from the history before writing a word:
|
|
48
|
+
last contact, open items, promises due.
|
|
49
|
+
2. Lead with what they care about, not what we did. Status they asked for first,
|
|
50
|
+
housekeeping last.
|
|
51
|
+
3. Reuse approved language wherever it exists. New claims and new commitments get
|
|
52
|
+
flagged in the draft, not smuggled in.
|
|
53
|
+
4. Match the established tone. Do not escalate warmth or formality without a reason.
|
|
54
|
+
5. Deliver the draft with a short cover note: what changed since last time, what needs
|
|
55
|
+
approval, what was left out on purpose.
|
|
56
|
+
|
|
57
|
+
Failure modes: re-promising something that already slipped (reads as not paying
|
|
58
|
+
attention), inventing enthusiasm the history doesn't support, and burying the one
|
|
59
|
+
thing the client actually asked about.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cross-tool-memory
|
|
3
|
+
description: One context you own, readable from Claude, GPT, Kimi, or Codex — a model switch is a recompile, not a re-teach.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- the loops in this .docket directory
|
|
8
|
+
- existing CLAUDE.md, AGENTS.md, and rules files
|
|
9
|
+
draft:
|
|
10
|
+
- updates to loop brief sections
|
|
11
|
+
- compiled context blocks
|
|
12
|
+
change:
|
|
13
|
+
- CLAUDE.md, AGENTS.md, and other compiled context files via docket compile
|
|
14
|
+
send: []
|
|
15
|
+
ask:
|
|
16
|
+
- rewriting a loop's warrant or reserved sections
|
|
17
|
+
- deleting anything from memory
|
|
18
|
+
never:
|
|
19
|
+
- storing secrets, tokens, or passwords in any loop file
|
|
20
|
+
reserved:
|
|
21
|
+
- what gets remembered at all — memory is curation, not accumulation
|
|
22
|
+
- any change to what an agent is allowed to do
|
|
23
|
+
record:
|
|
24
|
+
- what was added to memory and its source
|
|
25
|
+
- what was pruned and why
|
|
26
|
+
- which context files were regenerated
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Brief
|
|
30
|
+
|
|
31
|
+
- The context lives here, in plain files, in your repo — not inside any one
|
|
32
|
+
assistant's opaque memory feature. The assistants are interchangeable; this
|
|
33
|
+
directory is not.
|
|
34
|
+
- Which tools are in play (Claude Code, Cursor, Codex, a local model) and which
|
|
35
|
+
compiled file each one reads.
|
|
36
|
+
- The curation standard: memory holds things that change future answers —
|
|
37
|
+
decisions, preferences, constraints, standards. Not transcripts.
|
|
38
|
+
|
|
39
|
+
# Procedure
|
|
40
|
+
|
|
41
|
+
1. After significant work in any tool, harvest: what was decided, what preference
|
|
42
|
+
was expressed, what standard emerged? One line each, into the right loop's
|
|
43
|
+
Brief section.
|
|
44
|
+
2. Prune as often as you add. Memory that grows without curation becomes noise
|
|
45
|
+
with a table of contents.
|
|
46
|
+
3. Warrant and reserved-list changes are never harvested automatically — a human
|
|
47
|
+
relaxing a rule once in conversation is not the rule changing.
|
|
48
|
+
4. Run `docket compile --target claude --write` and `--target agents --write` so
|
|
49
|
+
every tool reads the same brain. The generated blocks are disposable; the loops
|
|
50
|
+
are the source of truth.
|
|
51
|
+
5. When switching models, carry nothing by hand. If the new tool starts cold,
|
|
52
|
+
something belongs in a loop file that isn't there yet — fix the file, not the chat.
|
|
53
|
+
|
|
54
|
+
Failure mode: letting one tool's built-in memory become the real memory. The moment
|
|
55
|
+
that happens, your context has a landlord.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: insurance-appeal
|
|
3
|
+
description: Build the appeal, cite the policy, assemble the evidence packet — stop before send.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- policy documents
|
|
8
|
+
- denial letter
|
|
9
|
+
- claim correspondence
|
|
10
|
+
- medical records already in the claim file
|
|
11
|
+
draft:
|
|
12
|
+
- appeal letter
|
|
13
|
+
- evidence summary
|
|
14
|
+
- timeline of the claim
|
|
15
|
+
change: []
|
|
16
|
+
send: []
|
|
17
|
+
ask:
|
|
18
|
+
- contacting the insurer
|
|
19
|
+
- contacting the doctor's office
|
|
20
|
+
- requesting new records
|
|
21
|
+
never:
|
|
22
|
+
- accepting or rejecting a settlement
|
|
23
|
+
- inventing symptoms or events not in the record
|
|
24
|
+
reserved:
|
|
25
|
+
- whether to appeal at all
|
|
26
|
+
- the final wording of anything the insurer will read
|
|
27
|
+
- signing and sending
|
|
28
|
+
record:
|
|
29
|
+
- every policy clause cited, with section numbers
|
|
30
|
+
- documents consulted and documents that could not be found
|
|
31
|
+
- claims made in the draft that lack a source in the record
|
|
32
|
+
- where the draft stopped and what a human must do next
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# Brief
|
|
36
|
+
|
|
37
|
+
- Policy number, plan year, and the exact denial reason code from the letter.
|
|
38
|
+
- The claim's timeline so far: dates of service, submission, denial, any prior calls.
|
|
39
|
+
- Appeals in this plan have a deadline (often 180 days from denial) — the date matters
|
|
40
|
+
more than the prose.
|
|
41
|
+
- What has already been said to the insurer. Never contradict the record.
|
|
42
|
+
- The insured person's actual account of events — the draft may only use what they
|
|
43
|
+
have confirmed, not what would be convenient.
|
|
44
|
+
|
|
45
|
+
# Procedure
|
|
46
|
+
|
|
47
|
+
1. Read the denial letter first. The appeal answers the stated reason, not a general
|
|
48
|
+
sense of unfairness.
|
|
49
|
+
2. Find the policy language the denial relies on, then the language that cuts the
|
|
50
|
+
other way. Quote both, with section numbers.
|
|
51
|
+
3. Build the evidence packet: what exists, what's missing, what a human would need to
|
|
52
|
+
request. Missing evidence is listed, not papered over.
|
|
53
|
+
4. Draft the appeal in plain, factual language. No threats, no speculation, no
|
|
54
|
+
symptoms or events that aren't in the record.
|
|
55
|
+
5. Stop. The draft ends with a checklist of what the human must verify before sending.
|
|
56
|
+
|
|
57
|
+
Known failure mode — the one this loop exists to prevent: an agent reading frustration
|
|
58
|
+
in a message ("I'm so sick of fighting this claim") as authorization, and sending the
|
|
59
|
+
appeal itself. Frustration is not permission. Nothing in this loop sends anything.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: marketing-brain
|
|
3
|
+
description: Marketing memory that compounds week over week — the messaging that already worked, the objections that keep coming back, the founder's actual voice.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- the positioning doc
|
|
8
|
+
- past campaigns and their results
|
|
9
|
+
- sales call notes
|
|
10
|
+
- competitor claims
|
|
11
|
+
draft:
|
|
12
|
+
- copy variants
|
|
13
|
+
- landing page sections
|
|
14
|
+
- launch posts
|
|
15
|
+
change:
|
|
16
|
+
- the swipe file of language that worked
|
|
17
|
+
send: []
|
|
18
|
+
ask:
|
|
19
|
+
- publishing anywhere public
|
|
20
|
+
- any claim with a number in it
|
|
21
|
+
never:
|
|
22
|
+
- claims about competitors we cannot support
|
|
23
|
+
- invented or made-up customer quotes or statistics
|
|
24
|
+
reserved:
|
|
25
|
+
- what the company is willing to claim in public
|
|
26
|
+
- the line between confident and unsupportable
|
|
27
|
+
- final approval on anything that ships
|
|
28
|
+
record:
|
|
29
|
+
- which surviving positioning lines the draft builds on
|
|
30
|
+
- every claim in the draft, marked supported or needs-evidence
|
|
31
|
+
- new objections or language patterns learned this week, added to the brief
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Brief
|
|
35
|
+
|
|
36
|
+
- Positioning that survived contact with real customers — the lines that made people
|
|
37
|
+
nod, kept verbatim. Also the graveyard: lines that tested well internally and died
|
|
38
|
+
in the wild.
|
|
39
|
+
- The recurring sales objections, in the customers' own words, and the answers that
|
|
40
|
+
actually landed.
|
|
41
|
+
- The founder's language: words they use, words they would never use. Copy that
|
|
42
|
+
doesn't sound like them gets rewritten anyway, so start in their voice.
|
|
43
|
+
- The explicit line between confident and unsupportable. Confident: "the
|
|
44
|
+
fastest way to X". Unsupportable: "the only way to X". This line is policy,
|
|
45
|
+
not taste.
|
|
46
|
+
|
|
47
|
+
# Procedure
|
|
48
|
+
|
|
49
|
+
1. Read the brief before writing. The whole value of this loop is that week 30
|
|
50
|
+
starts where week 29 ended, not from a blank page.
|
|
51
|
+
2. Draft from surviving language outward. New angles are welcome but marked as
|
|
52
|
+
untested.
|
|
53
|
+
3. Every factual claim gets a tag: supported (with the source) or needs-evidence.
|
|
54
|
+
A claim without a tag doesn't ship.
|
|
55
|
+
4. After anything ships, write down what happened — the memory only compounds if
|
|
56
|
+
results flow back in.
|
|
57
|
+
5. Never resolve the bold-vs-unsupported call alone. When a line sits on the border,
|
|
58
|
+
it goes to the human with the argument for each side.
|
|
59
|
+
|
|
60
|
+
Failure mode: drift. Fifty small rewrites by a helpful agent and the company sounds
|
|
61
|
+
like everyone else. The memory file is the anchor; when in doubt, sound like the
|
|
62
|
+
founder, not like marketing.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ticket-handoff
|
|
3
|
+
description: Turn messy work into tickets another human — or another agent — can pick up cold: source, owner, status, blocker, warrant, record.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- the conversation or incident being handed off
|
|
8
|
+
- the existing backlog
|
|
9
|
+
- team ownership docs
|
|
10
|
+
draft:
|
|
11
|
+
- ticket title and body
|
|
12
|
+
- suggested owner and priority
|
|
13
|
+
change:
|
|
14
|
+
- ticket status on tickets this loop created
|
|
15
|
+
send: []
|
|
16
|
+
ask:
|
|
17
|
+
- assigning a ticket to a person
|
|
18
|
+
- setting priority above default
|
|
19
|
+
- closing anyone else's ticket
|
|
20
|
+
never:
|
|
21
|
+
- deleting tickets
|
|
22
|
+
- editing another person's ticket description
|
|
23
|
+
reserved:
|
|
24
|
+
- who actually owns what
|
|
25
|
+
- priority calls that affect other people's weeks
|
|
26
|
+
record:
|
|
27
|
+
- every ticket created, with a link back to its source
|
|
28
|
+
- what was NOT filed, and why (duplicate, out of scope, needs a human call)
|
|
29
|
+
- open questions the ticket could not answer
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Brief
|
|
33
|
+
|
|
34
|
+
- The team's real ownership map — who owns which surface, including the unofficial
|
|
35
|
+
truths ("the doc says infra, but ask Dana first").
|
|
36
|
+
- Ticket conventions: title format, required fields, what counts as a blocker vs a
|
|
37
|
+
dependency, the priority scale as actually used.
|
|
38
|
+
- The backlog's known duplicates and graveyards, so the same ghost doesn't get filed
|
|
39
|
+
a fourth time.
|
|
40
|
+
- What a good ticket looks like here: reproducible, scoped, with the source linked —
|
|
41
|
+
not a paragraph of vibes.
|
|
42
|
+
|
|
43
|
+
# Procedure
|
|
44
|
+
|
|
45
|
+
1. Every ticket carries six fields or it isn't done: source (where this came from,
|
|
46
|
+
linked), owner (suggested, not assigned), status, blocker, warrant (what the
|
|
47
|
+
assignee may and may not do), and record (what evidence closes it).
|
|
48
|
+
2. Search the backlog before filing. A duplicate found is a record line, not a
|
|
49
|
+
new ticket.
|
|
50
|
+
3. Write the ticket so a stranger could start it cold. If it needs the original
|
|
51
|
+
conversation to make sense, the ticket isn't finished — the whole point is that
|
|
52
|
+
the context travels with the work.
|
|
53
|
+
4. Suggest owner and priority with reasons; a human confirms both. Suggesting is
|
|
54
|
+
drafting, assigning is sending.
|
|
55
|
+
5. Close the handoff with the record: filed, skipped, and unresolved — so the next
|
|
56
|
+
agent (or human) trusts the state without re-reading everything.
|
|
57
|
+
|
|
58
|
+
Failure mode: tickets that are really just chat transcripts with a title. Handing off
|
|
59
|
+
work means handing off the context, the warrant, and the definition of done.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: travel-morning
|
|
3
|
+
description: Plan a morning in an unfamiliar city around how you actually travel — not how a guidebook thinks you should.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- maps and transit schedules
|
|
8
|
+
- opening hours
|
|
9
|
+
- reviews
|
|
10
|
+
- weather
|
|
11
|
+
draft:
|
|
12
|
+
- the morning plan
|
|
13
|
+
- a backup plan for rain or closures
|
|
14
|
+
change: []
|
|
15
|
+
send: []
|
|
16
|
+
ask:
|
|
17
|
+
- any reservation or booking
|
|
18
|
+
- anything that costs money
|
|
19
|
+
never:
|
|
20
|
+
- booking anything nonrefundable
|
|
21
|
+
reserved:
|
|
22
|
+
- spending money
|
|
23
|
+
- changing the day's anchor commitments (flights, meetings, people)
|
|
24
|
+
record:
|
|
25
|
+
- total walking distance and longest single stretch
|
|
26
|
+
- which preferences shaped the plan and which were traded off
|
|
27
|
+
- what was rejected and why (too far, too crowded, violates a food rule)
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# Brief
|
|
31
|
+
|
|
32
|
+
- Walking tolerance: how far is pleasant, how far is a death march. Uphill counts double.
|
|
33
|
+
- Food rules: allergies, hard nos, and "will try anything once" — these are different
|
|
34
|
+
categories and must not be blended.
|
|
35
|
+
- Known time-sinks this traveler refuses: queues over 20 minutes, attractions that
|
|
36
|
+
exist for photos, anything requiring a timed ticket bought three days ago.
|
|
37
|
+
- Pace: one anchor thing per morning, or a packed itinerary? Written here, not inferred
|
|
38
|
+
from enthusiasm the night before.
|
|
39
|
+
- Hard constraints of the day: checkout times, meeting times, who else is coming.
|
|
40
|
+
|
|
41
|
+
# Procedure
|
|
42
|
+
|
|
43
|
+
1. Start from the day's fixed points and work backward — the plan serves the
|
|
44
|
+
commitments, not the reverse.
|
|
45
|
+
2. Pick one anchor (the thing that would make the morning feel worth it), then arrange
|
|
46
|
+
food and wandering around it.
|
|
47
|
+
3. Check everything against the rules: distance, opening hours, food constraints,
|
|
48
|
+
queue reputation. A plan that violates a written rule is wrong even if it's great.
|
|
49
|
+
4. Always produce the rain/closure fallback. A plan with no plan B is half a plan.
|
|
50
|
+
5. Present the plan with its tradeoffs stated ("skipped X because it's 40 minutes of
|
|
51
|
+
walking uphill") so the human can overrule with full information.
|
|
52
|
+
|
|
53
|
+
Failure mode: optimizing for "top ten" lists instead of the written preferences.
|
|
54
|
+
The whole point of this loop is that the preferences are already known.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weekly-planning
|
|
3
|
+
description: Propose the week — priorities, tradeoffs, and what has to move — but change nothing.
|
|
4
|
+
version: 1
|
|
5
|
+
warrant:
|
|
6
|
+
read:
|
|
7
|
+
- calendar
|
|
8
|
+
- task list
|
|
9
|
+
- last week's plan and what actually happened
|
|
10
|
+
draft:
|
|
11
|
+
- the week plan
|
|
12
|
+
- proposed moves with reasons
|
|
13
|
+
change: []
|
|
14
|
+
send: []
|
|
15
|
+
ask:
|
|
16
|
+
- moving any calendar event
|
|
17
|
+
- declining any meeting
|
|
18
|
+
- anything involving other people's time
|
|
19
|
+
never:
|
|
20
|
+
- family dinners, family commitments, or family events
|
|
21
|
+
- workouts or workout blocks
|
|
22
|
+
- cancelling anything without an explicit yes on that specific thing
|
|
23
|
+
reserved:
|
|
24
|
+
- what actually matters this week
|
|
25
|
+
- every calendar change, one by one — approving the plan is not approving the moves
|
|
26
|
+
record:
|
|
27
|
+
- the proposed plan and every tradeoff it makes
|
|
28
|
+
- what got protected and what got sacrificed
|
|
29
|
+
- the difference between last week's plan and last week's reality
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Brief
|
|
33
|
+
|
|
34
|
+
- Standing priorities and their real order — not the aspirational order.
|
|
35
|
+
- Recurring constraints: family commitments, workouts, school pickup, the meeting that
|
|
36
|
+
cannot move even though everyone wishes it could.
|
|
37
|
+
- The rules for what can move: deep work can shift within a day; anything with another
|
|
38
|
+
human in it needs their consent, which means it needs my approval first.
|
|
39
|
+
- How much focused work per day is realistic. Last week's reality is the calibration,
|
|
40
|
+
not last week's intention.
|
|
41
|
+
|
|
42
|
+
# Procedure
|
|
43
|
+
|
|
44
|
+
1. Start with reality: diff last week's plan against what actually happened. Carry the
|
|
45
|
+
lesson, not the guilt.
|
|
46
|
+
2. Place the immovables first — the reserved list above is a hard floor, not a
|
|
47
|
+
preference.
|
|
48
|
+
3. Fit the top priorities into the remaining space. If they don't fit, say so — a plan
|
|
49
|
+
that pretends everything fits is a lie with a nice layout.
|
|
50
|
+
4. Propose specific moves with reasons: "move X to Thursday because Y". Never make the
|
|
51
|
+
move. The plan is a proposal; the calendar is someone else's to change.
|
|
52
|
+
5. End with tradeoffs, stated plainly: what this week's plan gives up and why.
|
|
53
|
+
|
|
54
|
+
Failure mode: silently rescheduling things to make the plan look clean. A tidy plan
|
|
55
|
+
that moved a family dinner is a failed plan, even if nobody notices until Thursday.
|