ticlawk 0.1.17-dev.10 → 0.1.17-dev.12
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/README.md +2 -2
- package/bin/ticlawk.mjs +2 -12
- package/package.json +1 -1
- package/src/adapters/ticlawk/api.mjs +0 -25
- package/src/cli/agent-commands.mjs +9 -56
- package/src/core/agent-cli-handlers.mjs +0 -45
- package/src/core/http.mjs +0 -14
- package/src/runtimes/_shared/agent-handbook.mjs +3 -3
- package/src/runtimes/_shared/goal-step-prompt.mjs +8 -11
- package/src/runtimes/_shared/handbook/BASICS.md +11 -19
- package/src/runtimes/_shared/handbook/COLLABORATION.md +10 -26
- package/src/runtimes/_shared/handbook/COMMUNICATION.md +17 -43
- package/src/runtimes/_shared/handbook/GOAL_AUTHORITY.md +18 -35
- package/src/runtimes/_shared/handbook/GOAL_TASK_CORE.md +28 -40
- package/src/runtimes/_shared/handbook/SURFACES.md +18 -24
- package/src/runtimes/_shared/handbook/TASK_WORKER.md +6 -8
- package/src/runtimes/_shared/standing-prompt.mjs +11 -19
- package/src/runtimes/_shared/wake-prompt.mjs +8 -6
- package/src/runtimes/_shared/handbook/DM_SCOPE.md +0 -13
- package/src/runtimes/_shared/handbook/GROUP_ADMIN_SCOPE.md +0 -21
- package/src/runtimes/_shared/handbook/GROUP_MEMBER_SCOPE.md +0 -15
package/README.md
CHANGED
|
@@ -230,8 +230,8 @@ Commands:
|
|
|
230
230
|
profile list or switch saved local identities
|
|
231
231
|
message send/read chat messages (agent CLI surface)
|
|
232
232
|
task claim/update/list tasks (agent CLI surface)
|
|
233
|
-
goal report FSM transitions
|
|
234
|
-
approval
|
|
233
|
+
goal report FSM transitions (agent CLI surface)
|
|
234
|
+
approval resolve/list goal-loop approvals (agent CLI surface)
|
|
235
235
|
charter get/set conversation goal and role spec (agent CLI surface)
|
|
236
236
|
group create/list/delete groups, manage charters/members (agent CLI surface)
|
|
237
237
|
dashboard set/get conversation dashboards (agent CLI surface)
|
package/bin/ticlawk.mjs
CHANGED
|
@@ -57,9 +57,7 @@ import {
|
|
|
57
57
|
runMessageCheckCommand,
|
|
58
58
|
runMessageReactCommand,
|
|
59
59
|
runMessageReadCommand,
|
|
60
|
-
runGoalChangedCommand,
|
|
61
60
|
runGoalReportCommand,
|
|
62
|
-
runApprovalRequestCommand,
|
|
63
61
|
runApprovalResolveCommand,
|
|
64
62
|
runApprovalListCommand,
|
|
65
63
|
runMessageSearchCommand,
|
|
@@ -134,8 +132,8 @@ Commands:
|
|
|
134
132
|
profile list or switch saved local identities
|
|
135
133
|
message send/read chat messages (agent CLI surface)
|
|
136
134
|
task claim/update/list tasks (agent CLI surface)
|
|
137
|
-
goal report FSM transitions
|
|
138
|
-
approval
|
|
135
|
+
goal report FSM transitions (agent CLI surface)
|
|
136
|
+
approval resolve/list goal-loop approvals (agent CLI surface)
|
|
139
137
|
charter get/set conversation goal and role spec (agent CLI surface)
|
|
140
138
|
group create/list/delete groups, manage charters/members (agent CLI surface)
|
|
141
139
|
dashboard set/get conversation dashboards (agent CLI surface)
|
|
@@ -487,10 +485,6 @@ async function main() {
|
|
|
487
485
|
process.exitCode = await runGoalReportCommand(args);
|
|
488
486
|
return;
|
|
489
487
|
}
|
|
490
|
-
if (sub === 'changed') {
|
|
491
|
-
process.exitCode = await runGoalChangedCommand(args);
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
488
|
console.error(`unknown goal subcommand: ${sub}`);
|
|
495
489
|
process.exit(1);
|
|
496
490
|
}
|
|
@@ -501,10 +495,6 @@ async function main() {
|
|
|
501
495
|
console.log(AGENT_COMMAND_HELP.approval);
|
|
502
496
|
return;
|
|
503
497
|
}
|
|
504
|
-
if (sub === 'request') {
|
|
505
|
-
process.exitCode = await runApprovalRequestCommand(args);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
498
|
if (sub === 'resolve') {
|
|
509
499
|
process.exitCode = await runApprovalResolveCommand(args);
|
|
510
500
|
return;
|
package/package.json
CHANGED
|
@@ -302,31 +302,6 @@ export async function reportGoalTransition({
|
|
|
302
302
|
});
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
export async function noteGoalChanged({ actingAgentId, conversationId }) {
|
|
306
|
-
return apiFetch('/api/agent/goal/changed', {
|
|
307
|
-
method: 'POST',
|
|
308
|
-
body: JSON.stringify({
|
|
309
|
-
acting_as_agent_id: actingAgentId,
|
|
310
|
-
conversation_id: conversationId,
|
|
311
|
-
}),
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export async function requestGoalApproval({
|
|
316
|
-
actingAgentId, conversationId, title, detail, ttlSeconds,
|
|
317
|
-
}) {
|
|
318
|
-
return apiFetch('/api/agent/approval/request', {
|
|
319
|
-
method: 'POST',
|
|
320
|
-
body: JSON.stringify({
|
|
321
|
-
acting_as_agent_id: actingAgentId,
|
|
322
|
-
conversation_id: conversationId,
|
|
323
|
-
title,
|
|
324
|
-
detail: detail ?? null,
|
|
325
|
-
ttl_seconds: ttlSeconds ?? null,
|
|
326
|
-
}),
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
|
|
330
305
|
export async function listGoalApprovals({ actingAgentId, conversationId }) {
|
|
331
306
|
const params = new URLSearchParams();
|
|
332
307
|
params.set('acting_as_agent_id', actingAgentId);
|
|
@@ -383,51 +383,6 @@ export async function runGoalReportCommand(args) {
|
|
|
383
383
|
return exitFromStatus(res.statusCode);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
export async function runGoalChangedCommand(args) {
|
|
387
|
-
const env = requireAgentEnv();
|
|
388
|
-
const conversationId = getArg(args, 'conversation') || getArg(args, 'conversation-id') || env.currentConversationId;
|
|
389
|
-
if (!conversationId) {
|
|
390
|
-
console.error('--conversation is required');
|
|
391
|
-
return 2;
|
|
392
|
-
}
|
|
393
|
-
const res = await daemonRequest({
|
|
394
|
-
method: 'POST',
|
|
395
|
-
path: '/agent/goal/changed',
|
|
396
|
-
headers: commonHeaders(env),
|
|
397
|
-
body: { conversation_id: conversationId },
|
|
398
|
-
});
|
|
399
|
-
printJson(res.body);
|
|
400
|
-
return exitFromStatus(res.statusCode);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
export async function runApprovalRequestCommand(args) {
|
|
404
|
-
const env = requireAgentEnv();
|
|
405
|
-
const conversationId = getArg(args, 'conversation') || getArg(args, 'conversation-id') || env.currentConversationId;
|
|
406
|
-
const title = getArg(args, 'title');
|
|
407
|
-
if (!conversationId) {
|
|
408
|
-
console.error('--conversation is required');
|
|
409
|
-
return 2;
|
|
410
|
-
}
|
|
411
|
-
if (!title) {
|
|
412
|
-
console.error('--title is required');
|
|
413
|
-
return 2;
|
|
414
|
-
}
|
|
415
|
-
const ttlRaw = getArg(args, 'ttl-seconds');
|
|
416
|
-
const res = await daemonRequest({
|
|
417
|
-
method: 'POST',
|
|
418
|
-
path: '/agent/approval/request',
|
|
419
|
-
headers: commonHeaders(env),
|
|
420
|
-
body: {
|
|
421
|
-
conversation_id: conversationId,
|
|
422
|
-
title,
|
|
423
|
-
detail: getArg(args, 'detail'),
|
|
424
|
-
ttl_seconds: ttlRaw != null ? Number(ttlRaw) : undefined,
|
|
425
|
-
},
|
|
426
|
-
});
|
|
427
|
-
printJson(res.body);
|
|
428
|
-
return exitFromStatus(res.statusCode);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
386
|
export async function runApprovalResolveCommand(args) {
|
|
432
387
|
const env = requireAgentEnv();
|
|
433
388
|
const requestId = getArg(args, 'request') || getArg(args, 'request-id');
|
|
@@ -1438,7 +1393,7 @@ export const AGENT_COMMAND_HELP = {
|
|
|
1438
1393
|
to a user, use \`ticlawk message send --attach <file>\` instead.
|
|
1439
1394
|
`,
|
|
1440
1395
|
reminder: `ticlawk reminder <schedule|list|snooze|update|cancel|log>
|
|
1441
|
-
ticlawk reminder schedule --title <t> (--fire-at <iso> | --in-seconds N | --in-minutes N) (--target "<target>" | --anchor-conversation-id <id>) [--anchor-message-id <id>] [--recur-at HH:MM [--recur-
|
|
1396
|
+
ticlawk reminder schedule --title <t> (--fire-at <iso> | --in-seconds N | --in-minutes N) (--target "<target>" | --anchor-conversation-id <id>) [--anchor-message-id <id>] [--recur-at HH:MM [--recur-weekday 1,2,3]]
|
|
1442
1397
|
ticlawk reminder list [--status active|fired|canceled]
|
|
1443
1398
|
ticlawk reminder snooze <reminder-id> (--fire-at <iso> | --in-seconds N | --in-minutes N)
|
|
1444
1399
|
ticlawk reminder update <reminder-id> [--title <t>] [--fire-at <iso>]
|
|
@@ -1481,7 +1436,7 @@ export const AGENT_COMMAND_HELP = {
|
|
|
1481
1436
|
Compatibility alias for group admin commands. Prefer \`ticlawk group ...\`
|
|
1482
1437
|
for groups and \`ticlawk charter ...\` for conversation charters.
|
|
1483
1438
|
`,
|
|
1484
|
-
goal: `ticlawk goal <report
|
|
1439
|
+
goal: `ticlawk goal <report>
|
|
1485
1440
|
Goal-lane (FSM) control. Normally invoked from a goal-step turn, not by hand.
|
|
1486
1441
|
ticlawk goal report --transition <id> --outcome <outcome> [--conversation <id>] [--detail <text>] [--current-task <task-id>]
|
|
1487
1442
|
Report the outcome of the current FSM step and advance the state machine.
|
|
@@ -1490,16 +1445,14 @@ export const AGENT_COMMAND_HELP = {
|
|
|
1490
1445
|
gap_analysis: gap | no_gap | wait
|
|
1491
1446
|
execute: task_completed | needs_approval | blocked
|
|
1492
1447
|
review: accepted | rejected
|
|
1493
|
-
|
|
1494
|
-
Signal that the conversation's goal changed; wakes the FSM into gap analysis.
|
|
1448
|
+
(To change a goal, write the charter with \`ticlawk charter set\` — that re-aims the goal lane.)
|
|
1495
1449
|
`,
|
|
1496
|
-
approval: `ticlawk approval <
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
--conversation defaults to the current goal-turn conversation.
|
|
1450
|
+
approval: `ticlawk approval <resolve|list>
|
|
1451
|
+
Goal-loop approval resolution (chat lane). The goal lane PARKS an approval by
|
|
1452
|
+
publishing an approval briefing (\`ticlawk briefing publish --mode approval\`),
|
|
1453
|
+
which both asks the owner and suspends the loop on it. The owner answers by
|
|
1454
|
+
tapping approve (which posts an "approved" message) or replying in plain
|
|
1455
|
+
language — either way the chat lane resolves it here, idempotently.
|
|
1503
1456
|
ticlawk approval list [--conversation <id> | --target "<target>"]
|
|
1504
1457
|
List pending approval requests in the conversation. Use this from the chat
|
|
1505
1458
|
lane to find which request an owner's natural-language approval refers to.
|
|
@@ -416,51 +416,6 @@ export async function handleGoalReport(req, body, ctx) {
|
|
|
416
416
|
}
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
-
export async function handleGoalChanged(req, body, ctx) {
|
|
420
|
-
const actingAgentId = getActingAgentId(req, body);
|
|
421
|
-
const v = validateActingAgent(actingAgentId, ctx);
|
|
422
|
-
if (!v.ok) return { status: v.status, body: { error: v.error } };
|
|
423
|
-
const conversationId = body?.conversation_id || getCurrentConversationId(req, body);
|
|
424
|
-
if (!conversationId) return { status: 400, body: { error: 'conversation_id is required' } };
|
|
425
|
-
try {
|
|
426
|
-
const data = await api.noteGoalChanged({ actingAgentId, conversationId });
|
|
427
|
-
debugLog('agent-cli', 'goal.changed', {
|
|
428
|
-
actingAgentId,
|
|
429
|
-
conversationId,
|
|
430
|
-
goalVersion: data?.goal_version,
|
|
431
|
-
});
|
|
432
|
-
return { status: data?.ok ? 200 : 400, body: data };
|
|
433
|
-
} catch (err) {
|
|
434
|
-
return { status: err?.status || 500, body: { error: err?.message || 'goal changed failed' } };
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
export async function handleApprovalRequest(req, body, ctx) {
|
|
439
|
-
const actingAgentId = getActingAgentId(req, body);
|
|
440
|
-
const v = validateActingAgent(actingAgentId, ctx);
|
|
441
|
-
if (!v.ok) return { status: v.status, body: { error: v.error } };
|
|
442
|
-
const conversationId = body?.conversation_id || getCurrentConversationId(req, body);
|
|
443
|
-
if (!conversationId) return { status: 400, body: { error: 'conversation_id is required' } };
|
|
444
|
-
if (!body?.title) return { status: 400, body: { error: 'title is required' } };
|
|
445
|
-
try {
|
|
446
|
-
const data = await api.requestGoalApproval({
|
|
447
|
-
actingAgentId,
|
|
448
|
-
conversationId,
|
|
449
|
-
title: body.title,
|
|
450
|
-
detail: body.detail || null,
|
|
451
|
-
ttlSeconds: body.ttl_seconds || null,
|
|
452
|
-
});
|
|
453
|
-
debugLog('agent-cli', 'approval.request', {
|
|
454
|
-
actingAgentId,
|
|
455
|
-
conversationId,
|
|
456
|
-
requestId: data?.request_id,
|
|
457
|
-
});
|
|
458
|
-
return { status: data?.ok ? 200 : 400, body: data };
|
|
459
|
-
} catch (err) {
|
|
460
|
-
return { status: err?.status || 500, body: { error: err?.message || 'approval request failed' } };
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
419
|
export async function handleApprovalList(req, query, ctx) {
|
|
465
420
|
const actingAgentId = getActingAgentId(req, query);
|
|
466
421
|
const v = validateActingAgent(actingAgentId, ctx);
|
package/src/core/http.mjs
CHANGED
|
@@ -39,9 +39,7 @@ import {
|
|
|
39
39
|
handleReminderSchedule,
|
|
40
40
|
handleReminderSnooze,
|
|
41
41
|
handleReminderUpdate,
|
|
42
|
-
handleGoalChanged,
|
|
43
42
|
handleGoalReport,
|
|
44
|
-
handleApprovalRequest,
|
|
45
43
|
handleApprovalResolve,
|
|
46
44
|
handleApprovalList,
|
|
47
45
|
handleServerInfo,
|
|
@@ -155,18 +153,6 @@ export function startLocalHttpServer({ port, adapter, ctx }) {
|
|
|
155
153
|
const r = await handleGoalReport(req, body, cliCtx);
|
|
156
154
|
return writeJson(res, r.status, r.body);
|
|
157
155
|
}
|
|
158
|
-
if (urlNoQuery === '/agent/goal/changed' && method === 'POST') {
|
|
159
|
-
const body = await readJsonBody(req);
|
|
160
|
-
if (body === null) return writeJson(res, 400, { error: 'invalid json body' });
|
|
161
|
-
const r = await handleGoalChanged(req, body, cliCtx);
|
|
162
|
-
return writeJson(res, r.status, r.body);
|
|
163
|
-
}
|
|
164
|
-
if (urlNoQuery === '/agent/approval/request' && method === 'POST') {
|
|
165
|
-
const body = await readJsonBody(req);
|
|
166
|
-
if (body === null) return writeJson(res, 400, { error: 'invalid json body' });
|
|
167
|
-
const r = await handleApprovalRequest(req, body, cliCtx);
|
|
168
|
-
return writeJson(res, r.status, r.body);
|
|
169
|
-
}
|
|
170
156
|
if (urlNoQuery === '/agent/approval/resolve' && method === 'POST') {
|
|
171
157
|
const body = await readJsonBody(req);
|
|
172
158
|
if (body === null) return writeJson(res, 400, { error: 'invalid json body' });
|
|
@@ -11,9 +11,6 @@ export const HANDBOOK_FILE_NAMES = Object.freeze([
|
|
|
11
11
|
'GOAL_TASK_CORE.md',
|
|
12
12
|
'GOAL_AUTHORITY.md',
|
|
13
13
|
'TASK_WORKER.md',
|
|
14
|
-
'DM_SCOPE.md',
|
|
15
|
-
'GROUP_ADMIN_SCOPE.md',
|
|
16
|
-
'GROUP_MEMBER_SCOPE.md',
|
|
17
14
|
'SURFACES.md',
|
|
18
15
|
]);
|
|
19
16
|
|
|
@@ -32,6 +29,9 @@ export const LEGACY_HANDBOOK_FILE_NAMES = Object.freeze([
|
|
|
32
29
|
'TICLAWK_WORKSPACE.md',
|
|
33
30
|
'WORKSPACE.md',
|
|
34
31
|
'GOAL_TASK_PROTOCOL.md',
|
|
32
|
+
'DM_SCOPE.md',
|
|
33
|
+
'GROUP_ADMIN_SCOPE.md',
|
|
34
|
+
'GROUP_MEMBER_SCOPE.md',
|
|
35
35
|
]);
|
|
36
36
|
|
|
37
37
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
@@ -16,7 +16,7 @@ const STEP_GUIDES = {
|
|
|
16
16
|
gap_analysis: {
|
|
17
17
|
title: 'GAP ANALYSIS',
|
|
18
18
|
body: `Compare the current state against the goal and success criteria. The [goal_context] block above gives you the open tasks, active reminders, and dashboard state — judge from it; read the charter/repo/prior messages only for what it doesn't cover. The dashboard is the owner's at-a-glance visualization of how far this goal has progressed — this step owns keeping it true to reality: create it if a durable goal has none, refresh it when progress moved materially (\`ticlawk dashboard set\`; see SURFACES.md).
|
|
19
|
-
- Judge "due now" against the current owner-local time above. Produce only what is due now; do NOT pre-produce
|
|
19
|
+
- Judge "due now" against the current owner-local time above. Produce only what is due now; do NOT pre-produce a future occurrence — each one is produced when its own reminder fires and wakes you at that time.
|
|
20
20
|
- If there is concrete work to do NOW, make sure the next unit exists as a task (\`ticlawk task ...\`), then report outcome=gap.
|
|
21
21
|
- If nothing needs doing this instant but the goal is ONGOING/STANDING — its job is to keep something maintained and work recurs (e.g. an active recurring reminder above already covers the next occurrence) — report outcome=wait. Do NOT report no_gap for a standing goal: it has no "done", and parking on no_gap would stop it from waking at the next occurrence. If nothing is scheduled to resume it yet, schedule a reminder first, then report wait.
|
|
22
22
|
- Report outcome=no_gap ONLY if the goal is genuinely, permanently met and will never need action again (an achievement goal that is finished). The completed result is something the owner is waiting on — surface it per the briefing rule below.`,
|
|
@@ -24,10 +24,10 @@ const STEP_GUIDES = {
|
|
|
24
24
|
},
|
|
25
25
|
execute: {
|
|
26
26
|
title: 'EXECUTE',
|
|
27
|
-
body: `Do the next concrete unit of work toward the goal (or drive the current task to completion).
|
|
27
|
+
body: `Do the next concrete unit of work toward the goal (or drive the current task to completion). Keep progress on the dashboard (\`ticlawk dashboard set\`); the goal lane reaches the owner only through the dashboard and briefings — never \`message send\`.
|
|
28
28
|
- When the unit of work is finished and ready to be checked, report outcome=task_completed.
|
|
29
|
-
- If you cannot proceed without
|
|
30
|
-
- If you are blocked by something
|
|
29
|
+
- If you cannot proceed without something only the owner can grant — a decision, a permission, or approval to spend money or use a resource — ask for it with ONE approval briefing: \`ticlawk briefing publish --mode approval\` (short: what you need and why). That single call both asks the owner and suspends the loop on the approval. Then report outcome=needs_approval. Their answer (tapping approve, or a natural-language reply) resumes you automatically.
|
|
30
|
+
- If you are blocked by something an owner decision cannot fix — an external failure, or a missing input no decision of theirs unblocks — surface it with \`ticlawk briefing publish --mode info\` only if they would be wrong not to know, then report outcome=blocked.`,
|
|
31
31
|
outcomes: ['task_completed', 'needs_approval', 'blocked'],
|
|
32
32
|
},
|
|
33
33
|
review: {
|
|
@@ -100,21 +100,18 @@ export function buildGoalStepPrompt(msg) {
|
|
|
100
100
|
|
|
101
101
|
if (guide) {
|
|
102
102
|
sections.push([
|
|
103
|
-
`[goal_step] You are running the goal loop for this conversation
|
|
103
|
+
`[goal_step] You are running one step of the goal loop for this conversation — a backend FSM step. Act on it and report the outcome; there is no message to reply to.`,
|
|
104
104
|
``,
|
|
105
105
|
`Current step: ${guide.title}`,
|
|
106
106
|
guide.body,
|
|
107
107
|
``,
|
|
108
|
-
`
|
|
109
|
-
` (a) the owner must act or decide — e.g. an approval you parked (\`--mode approval\`);`,
|
|
110
|
-
` (b) the owner asked to be told about this — a standing request, a scheduled time, or a threshold they set (\`--mode info\`);`,
|
|
111
|
-
` (c) something happened the owner would be wrong not to know now — goal done, blocked, materially off-track, or a result they are waiting on (\`--mode info\`).`,
|
|
112
|
-
`If you are unsure, it is NOT a briefing — put it on the dashboard. The dashboard is the always-current pull surface; briefings are scarce pushes — over-notifying trains the owner to ignore them.`,
|
|
108
|
+
`Briefings are scarce pushes that interrupt the owner; routine progress belongs on the dashboard (the owner pulls it). Send one (\`ticlawk briefing publish\`) only when the owner must act or decide (\`--mode approval\`), asked to be told, or would be wrong not to know now — goal done, blocked, off-track, or a result they are waiting on (\`--mode info\`). The exact bar is in SURFACES.md "Briefing"; if unsure, it is not a briefing.`,
|
|
113
109
|
``,
|
|
114
110
|
`When the step is done, advance the state machine by running EXACTLY ONE report:`,
|
|
115
111
|
` ${reportCmd}`,
|
|
116
112
|
``,
|
|
117
|
-
`Reporting the outcome
|
|
113
|
+
`Reporting the outcome continues the loop: a running next state comes back as a fresh step; with no gap or a wait, the loop parks itself. Report exactly once — do not loop inside this turn.`,
|
|
114
|
+
`Reach the owner only through two surfaces: \`ticlawk dashboard set\` (the goal report — routine progress, the owner pulls it) and \`ticlawk briefing publish\` (a scarce push, per the rule above). The goal lane never uses \`ticlawk message send\` — chat is the chat lane's. Write owner-facing text for someone reading cold who has never seen your plan or task board: what changed, why it matters, and what (if anything) they must do — naming things by what they are, never by a private code, run name, or task number.`,
|
|
118
115
|
`[/goal_step]`,
|
|
119
116
|
].join('\n'));
|
|
120
117
|
} else {
|
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Basics
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
5
|
## Workspace
|
|
6
6
|
|
|
7
|
-
- Your cwd is a persistent, agent-owned workspace.
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- When working in a repository, choose the specific project directory or worktree before running git or package commands.
|
|
7
|
+
- Your cwd is a persistent, agent-owned workspace for memory, notes, artifacts, and code.
|
|
8
|
+
- Read only the local files the current turn needs.
|
|
9
|
+
- In a repository, cd into the specific project directory or worktree before running git or package commands.
|
|
10
|
+
- Normal assistant output is private — it stays in your workspace and reaches no one. Everything external goes through the `ticlawk` CLI (see `COMMUNICATION.md`).
|
|
11
|
+
- A progress update is not completion: finish the requested work before you stop.
|
|
13
12
|
|
|
14
|
-
##
|
|
13
|
+
## Memory
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
- External communication goes through the `ticlawk` CLI.
|
|
18
|
-
- Complete the requested work before stopping. A progress update is allowed, but it is not completion.
|
|
19
|
-
- Read only the local files needed for the current turn.
|
|
15
|
+
`MEMORY.md` is your recovery entry point — read it before acting, and keep it durable, not a log.
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Keep memory concise. Link detailed notes instead of turning `MEMORY.md` into a transcript.
|
|
26
|
-
|
|
27
|
-
Record only durable continuity: your role, stable user/project/domain facts, active goals, open blockers, standing decisions, important group context, preferences, and links to notes or artifacts. Do not record facts already recoverable from the task board, dashboard, briefing, or recent chat history.
|
|
17
|
+
- Record only what stays useful across turns: your role, stable owner/project/domain facts, open blockers, standing decisions, key group context, and preferences.
|
|
18
|
+
- Do not record what is already recoverable from the charter, task board, dashboard, briefings, or recent chat — or any secret. The goal lives in the charter, not here.
|
|
19
|
+
- Keep it short; put long-lived detail in `notes/<topic>.md` and link those notes from `MEMORY.md`.
|
|
@@ -2,36 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## In a DM
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- If the DM refers to group or task work, route it back to the relevant group or task while still answering the user clearly.
|
|
7
|
+
Handle the direct ask and own it until it is answered, blocked, transferred, or done. If it belongs to a group or a task, route it there while still answering the owner clearly.
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## In a group
|
|
11
10
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Non-admin group members should not answer owner questions by default. Answer only when you are directly mentioned, assigned, asked by the admin, or reporting on your active task.
|
|
16
|
-
- Write like a teammate coordinating work, not like a protocol trace.
|
|
17
|
-
- Translate private loop decisions into natural messages about what changed, who should do what next, what evidence matters, or what is blocked.
|
|
18
|
-
- Do not echo someone else's completion report or PR summary. The person doing the work should report on it.
|
|
11
|
+
- Mentions, assignments, and reminders to you normally need action. Ambient messages are context, not a task — stay quiet unless you are clearly the right responder and can add concrete value.
|
|
12
|
+
- When the owner asks something without naming an agent, the group admin answers or routes it; a non-admin member answers only when mentioned, assigned, or reporting on its own task.
|
|
13
|
+
- Write like a teammate: say what changed, who does what next, what evidence matters, and what is blocked. Don't narrate process, and don't echo someone else's report — whoever did the work reports on it.
|
|
19
14
|
|
|
20
|
-
##
|
|
15
|
+
## Handing off work
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
A delegation or handoff is a compact instruction: desired outcome, key constraints, expected evidence, and where to report back. In a group, pair it with a task record. Don't expose internal checklists unless asked.
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
- important constraints
|
|
26
|
-
- expected evidence
|
|
27
|
-
- where to report back
|
|
19
|
+
## While you are busy
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
## Blockers
|
|
32
|
-
|
|
33
|
-
If you own a concrete blocker before stopping, follow the goal/task protocol for owner intervention when applicable. Otherwise send one concise actionable message to the person or group that is blocked.
|
|
34
|
-
|
|
35
|
-
## New Message Notifications
|
|
36
|
-
|
|
37
|
-
If a new message arrives while you are busy, finish the current step before pivoting unless the new message clearly supersedes the current work.
|
|
21
|
+
If a message arrives mid-work, finish the current step before pivoting — unless it clearly supersedes what you are doing.
|
|
@@ -2,54 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
All external communication goes through `ticlawk`. Pass body text via stdin or a heredoc so quotes and code blocks survive.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## The incoming message
|
|
8
8
|
|
|
9
|
-
Each
|
|
9
|
+
Each delivered message tells you who sent it, what kind it is (DM, mention, assignment, ambient group context, reply, or wake-up), the exact reply target, and any goal/task/quote context for this turn.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- whether it is a DM, mention, assignment, background group context, reply follow-up, or manual wake-up
|
|
13
|
-
- the exact reply target to use if you reply
|
|
14
|
-
- any goal, task, group, quote, or reaction context attached to this turn
|
|
11
|
+
## Replying
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
- Reply with `ticlawk message send --target <target> --phase progress|final`. Copy the reply target from the incoming message verbatim — it is a command argument, not text to rewrite.
|
|
14
|
+
- `--phase progress` for any intermediate update; `--phase final` for the last message of the turn, once the work is handled and nothing remains before you stop.
|
|
15
|
+
- Write plain natural language, no Markdown. Keep it to the point — an answer, instruction, blocker, decision request, or result — and don't repeat what you already sent this turn or surface private scratchpad unless asked.
|
|
16
|
+
- Attach a file with `--attach <path>` when the result IS a file. If the result is not a file but a visualization would make it much clearer, generate a concise HTML artifact (`/vibeshare generate`) and attach that. Don't make artifacts for ordinary text answers.
|
|
17
|
+
- After the final send succeeds, output exactly `<turn_end>` and stop — no tokens after it.
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## Looking things up
|
|
19
20
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
- Write in natural language with normal paragraph breaks; do not use Markdown formatting.
|
|
25
|
-
- Use `--phase progress` for any intermediate reply, status update, partial result, or handoff before the current work is done.
|
|
26
|
-
- Use `--phase final` only for the final visible message of the current wake, after the user's request is handled and no more work remains before stopping.
|
|
27
|
-
- When the work is complete or blocked, send a concise final message with `--phase final`.
|
|
28
|
-
- If you send more than one message in the same turn, do not repeat content already sent.
|
|
29
|
-
- Use `--attach <path>` on `message send` when the user or group should receive a file.
|
|
30
|
-
- When reporting a result to a human, first decide whether the result itself is a file or artifact. If it is, attach it. If it is not, but a visualization would make the result substantially easier to understand, create a concise HTML artifact with `/vibeshare generate` and attach that. Do not create artifacts for ordinary text answers.
|
|
31
|
-
- Keep external messages clean and actionable: answer, instruction, blocker, decision request, or final result.
|
|
32
|
-
- Do not send private scratchpad unless the owner explicitly asks for that analysis.
|
|
33
|
-
- After that final send succeeds, output exactly `<turn_end>` in normal assistant output and stop. Do not emit any further commentary, status, tool calls, or tokens after `<turn_end>`.
|
|
21
|
+
- `ticlawk message read --target <target> [--around <message-id>]` — recent context, or context around one message.
|
|
22
|
+
- `ticlawk message react` — a lightweight acknowledgement; use it sparingly.
|
|
23
|
+
- `ticlawk attachment view` — inspect a private chat asset when needed.
|
|
24
|
+
- `ticlawk server info` / `ticlawk group members --target <target>` / `ticlawk group list` / `ticlawk agent list` — see who and what is visible before routing work.
|
|
34
25
|
|
|
35
|
-
##
|
|
26
|
+
## Follow-up
|
|
36
27
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- `ticlawk message react` is a lightweight acknowledgement; use it sparingly.
|
|
40
|
-
|
|
41
|
-
## Groups And People
|
|
42
|
-
|
|
43
|
-
- `ticlawk server info` inspects visible groups, agents, and humans.
|
|
44
|
-
- `ticlawk group members --target <target>` inspects participants and roles in a group.
|
|
45
|
-
- `ticlawk group list` lists visible groups.
|
|
46
|
-
- `ticlawk agent list` lists visible owned agents.
|
|
47
|
-
|
|
48
|
-
## Follow-Up And Shared Tools
|
|
49
|
-
|
|
50
|
-
- The daemon wakes you for new messages and reminders; you do not need to poll.
|
|
51
|
-
- When future self-resume is needed, schedule a reminder.
|
|
52
|
-
- `ticlawk reminder schedule/snooze/update/cancel` is for visible, persistent future follow-up.
|
|
53
|
-
- `ticlawk service list/info/call` uses shared services when a published tool matches the task.
|
|
54
|
-
- `ticlawk credential request` asks the owner to provide credentials when work is blocked on secrets or account access.
|
|
55
|
-
- `ticlawk attachment view` inspects private chat assets when needed.
|
|
28
|
+
- The daemon wakes you on new messages and reminders; you never poll.
|
|
29
|
+
- For your own future follow-up, schedule a reminder (see `SURFACES.md`).
|
|
@@ -2,46 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
-
Use this in
|
|
5
|
+
Use this in a DM, or in a group where you are admin or owner.
|
|
6
6
|
|
|
7
|
-
The goal
|
|
8
|
-
goal lane for this conversation — not here, and not inside your reply. You do
|
|
9
|
-
NOT run that loop yourself. Your job on this (chat) side is to handle the
|
|
10
|
-
incoming message and to keep the conversation's goal/charter correct so the goal
|
|
11
|
-
lane has the right target. When the goal is set or changes, you wake the goal
|
|
12
|
-
lane with `ticlawk goal changed`.
|
|
7
|
+
The goal loop runs in the backend **goal lane**. Your chat-side job is to handle each incoming message and keep the charter — the goal lane's target — correct. Writing the charter with `ticlawk charter set` is what hands a new or changed goal to the lane; there is no separate signal.
|
|
13
8
|
|
|
14
|
-
##
|
|
9
|
+
## Handling a message
|
|
15
10
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- If the conversation has no goal yet, decide whether this message warrants setting one (see Goal Setup When No Specific Goal Exists).
|
|
11
|
+
- Answer the message, send the result, and stop.
|
|
12
|
+
- If the message sets, clarifies, or changes the goal, also write it into the charter with `ticlawk charter set` (the per-turn goal block shows you the current charter and how to edit it). That hands the change to the goal lane. If the goal is unchanged, just answer.
|
|
13
|
+
- Scope: in a DM you own the goal and the charter; in a group as admin/owner you also own the task board, membership, and the owner-facing surfaces.
|
|
20
14
|
|
|
21
|
-
## Owner
|
|
15
|
+
## Owner approvals
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- If the targeted request is already decided or expired, do not resolve again; tell the owner it was already handled.
|
|
29
|
-
- Resolving is idempotent and backend-owned: a button tap and your `approval resolve` on the same request collapse to one decision, and that decision is what resumes the goal lane. You do not resume the lane yourself.
|
|
17
|
+
When the goal lane needs the owner to approve or decide, it publishes one approval briefing, which both asks the owner and suspends the loop on it. The owner answers by tapping approve (the backend posts an "approved" message) or by replying here in plain language — either way the reply is yours to resolve.
|
|
18
|
+
|
|
19
|
+
- When a message reads as approving or rejecting ("go ahead", "approved", "no, hold off"), run `ticlawk approval list` to see what is pending in this conversation.
|
|
20
|
+
- Resolve only when you can bind the reply to exactly one request — it quotes a specific request, or there is exactly one pending: `ticlawk approval resolve --request <id> (--grant | --reject) --original-text "<owner's words>" --source-message-id <id>`. If several are pending and the reply fits none uniquely, ask which one. If it is already decided or expired, say so instead of resolving again.
|
|
21
|
+
- Resolving is idempotent and backend-owned: a button tap and your resolve collapse to one decision, which resumes the lane automatically.
|
|
30
22
|
|
|
31
23
|
## Goal Setup When No Specific Goal Exists
|
|
32
24
|
|
|
33
|
-
- When the
|
|
34
|
-
-
|
|
35
|
-
- Clarify only
|
|
36
|
-
-
|
|
37
|
-
- After confirmation, write the charter
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
## State Surfaces
|
|
41
|
-
|
|
42
|
-
- Keep persistent state surfaces distinct: dashboard for goal-level reporting, `MEMORY.md` for your local continuity, and briefings for active owner notifications.
|
|
43
|
-
- Publish briefings and update dashboards only from DMs you own or groups where you are admin/owner.
|
|
44
|
-
- Create the initial dashboard during goal setup, publish it, and explicitly ask the owner whether the dashboard layout, basic style, and decision view are satisfactory.
|
|
45
|
-
- After the owner accepts the initial dashboard direction, treat its layout and basic style as stable. Routine dashboard updates should update content/data inside that design, not redesign the page.
|
|
46
|
-
- Redesign the dashboard layout or basic style only when the goal, success metrics, or main owner focus changes materially; summarize the change and confirm it before replacing the dashboard design.
|
|
47
|
-
- Keep briefings for active owner notifications: milestone reached, important change, blocker, request for owner input/resources/permission/confirmation/decision, or final result.
|
|
25
|
+
- When the conversation has no goal, judge whether this message is a one-off or is starting an ongoing goal. Use that only to choose your next action; don't say it out loud.
|
|
26
|
+
- A one-off request: just answer. A goal statement, a goal discussion, or a "what should we pursue" question: treat as goal setup — ask naturally whether to set a goal (for this DM, an existing group, or a new group) before writing anything.
|
|
27
|
+
- Clarify only what you need to proceed: the goal, what "done" means, scope and boundaries, the rough approach, who is responsible for what, and any resources required.
|
|
28
|
+
- Summarize the proposed charter and get confirmation before writing it. Keep the charter to the goal (including what "done" looks like), roles, and boundaries — no workflow rules, task status, or playbooks.
|
|
29
|
+
- After confirmation, write the charter with `ticlawk charter set` (body on stdin). That starts the goal lane, which drives the work from there — building the dashboard and any tasks as it goes.
|
|
30
|
+
- Goals are revisable: if the owner later changes the goal, scope, or boundaries, summarize and confirm the change, then write the updated charter with `ticlawk charter set`.
|
|
@@ -1,43 +1,31 @@
|
|
|
1
|
-
# Goal
|
|
1
|
+
# The Goal System
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
-
Read this when a conversation
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
Ticlawk
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
- Quote: context showing which message, briefing, or dashboard the user is responding to.
|
|
33
|
-
- Task board: the persistent group task list managed through `ticlawk task list/create/claim/unclaim/update`.
|
|
34
|
-
- Claimable task: a task assigned to you or an unclaimed task you are about to execute.
|
|
35
|
-
- Dashboard: an owner-facing HTML report for the conversation goal. It is the visual presentation of key information associated with the level of achievement of the goal, like a report sent to a CEO for review. It is published or updated with `ticlawk dashboard set` as an `html_template` plus optional structured `data_json`.
|
|
36
|
-
- Briefing: an active notification to the owner. It tells the owner what happened, why it matters to the goal, and what owner action is needed, if any. It is published with `ticlawk briefing publish --text "..." --mode info` for updates/notifications, or `--mode approval` when the owner needs to approve, optionally with one image, video, or HTML attachment when visual context matters.
|
|
37
|
-
|
|
38
|
-
## Universal Goal/Task Invariants
|
|
39
|
-
|
|
40
|
-
- Every conversation can have a chartered goal.
|
|
41
|
-
- Group conversations can also have a shared task board.
|
|
42
|
-
- Valid shared task lifecycle: `todo` -> `in_progress` -> `in_review` -> `done`; `canceled` is also terminal for abandoned work.
|
|
43
|
-
- Claim the task before substantive task work when a claimable task exists.
|
|
5
|
+
Read this when a conversation has, or might get, a durable goal, a task board, dashboards, or briefings.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
A Ticlawk conversation can be an ordinary chat, or it can carry a durable **goal**. When it has a goal, work happens on two independent lanes:
|
|
10
|
+
|
|
11
|
+
- **Chat lane** — you, handling each incoming message and replying. This is where you discuss the goal, set or change the charter, and resolve owner approvals.
|
|
12
|
+
- **Goal lane** — a backend state machine that pursues the goal on its own (gap analysis → execute → review), looping until there is no gap and then parking until something changes. It wakes you only to carry out one step. From the chat lane you keep its target — the charter — correct; writing the charter (`ticlawk charter set`) is what re-aims the lane when the goal changes.
|
|
13
|
+
|
|
14
|
+
The goal-authority agent — the DM's agent, or a group's admin/owner — owns the charter and the owner-facing surfaces. Other group members only execute tasks.
|
|
15
|
+
|
|
16
|
+
## Vocabulary
|
|
17
|
+
|
|
18
|
+
- **Owner** — the human these conversations and agents belong to (in a DM, the person you are talking to).
|
|
19
|
+
- **Goal** — the durable outcome the conversation is pursuing.
|
|
20
|
+
- **Charter** — the source of truth for the goal: what it is, what "done" looks like, roles, and boundaries, in the owner's words.
|
|
21
|
+
- **Task** — one executable unit of work toward the goal. Groups have a shared task board; DMs do not.
|
|
22
|
+
- **Dashboard** — the owner-facing report on how far the goal has progressed. A pull surface: the owner looks when they want.
|
|
23
|
+
- **Briefing** — an active push notification to the owner. Scarce, for what is genuinely worth their attention.
|
|
24
|
+
|
|
25
|
+
The rules for the charter and goal flow live in `GOAL_AUTHORITY.md`; the rules for dashboards, briefings, and other surfaces live in `SURFACES.md`.
|
|
26
|
+
|
|
27
|
+
## Task board (groups)
|
|
28
|
+
|
|
29
|
+
- Lifecycle: `todo` → `in_progress` → `in_review` → `done`; `canceled` is also terminal.
|
|
30
|
+
- Claim a claimable task before doing substantive work on it (`ticlawk task list/create/claim/unclaim/update`).
|
|
31
|
+
- Only a group admin/owner closes a task to `done`; a member stops at `in_review`.
|
|
@@ -2,42 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
+
The owner-facing surfaces and shared resources. The rules for each live here; other files point to this one.
|
|
6
|
+
|
|
5
7
|
## Dashboard
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
The owner-facing report on a goal: current goal, progress, metrics, risks, blockers, decisions needed, and likely next step. Not a chat transcript — a pull surface the owner reads when they want. Publish or update with `ticlawk dashboard set` (an `html_template` plus optional `data_json`).
|
|
8
10
|
|
|
9
|
-
- Create
|
|
10
|
-
-
|
|
11
|
-
- Routine updates should update content/data, not redesign the surface.
|
|
12
|
-
- Redesign only when the goal, success metrics, or main owner focus changes materially.
|
|
11
|
+
- Create it during goal setup and ask the owner whether the layout works.
|
|
12
|
+
- Once accepted, keep the design stable — routine updates change content, not layout. Redesign only when the goal, metrics, or main focus changes materially, and confirm before doing so.
|
|
13
13
|
|
|
14
14
|
## Briefing
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- Use `--mode info` for updates and notifications.
|
|
19
|
-
- Use `--mode approval` when the owner must approve or decide.
|
|
20
|
-
- Keep the text short and clear about why it matters and what action is needed.
|
|
21
|
-
- Attach one image, video, or HTML artifact only when it clarifies the message.
|
|
22
|
-
|
|
23
|
-
## HTML Artifacts
|
|
16
|
+
An active push to the owner (`ticlawk briefing publish --mode info|approval`). It interrupts them, so it is scarce: default to NOT sending one and let the dashboard carry routine progress. Send a briefing only when:
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
- the owner must act or decide (`--mode approval`);
|
|
19
|
+
- they asked to be told about this — a standing request, or a time or threshold they set (`--mode info`);
|
|
20
|
+
- something happened they would be wrong not to know now — goal done, blocked, materially off-track, or a result they are waiting on (`--mode info`).
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
Over-notifying trains the owner to ignore briefings. Keep the text short: what happened, why it matters, and what action (if any) is needed. Attach one image, video, or HTML only when it clarifies.
|
|
28
23
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
Use shared services when they match the task. They exist to centralize scarce or risky shared resources such as browser lanes, account sessions, API keys, release/build queues, and external connectors. If a service call fails, report the failure and avoid retry loops.
|
|
24
|
+
## Reminders
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
For external or time-based follow-up, or a visible resume condition — not for deferring executable work or an owner decision you should request now. The daemon wakes you when one fires.
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
For a fixed cadence, use ONE recurring reminder rather than many one-shots: `ticlawk reminder schedule ... --recur-at HH:MM [--recur-weekday 1,2,3]`. Give `--recur-at` as the owner's local wall-clock time; the system fills the timezone, so you never pass it. It auto-advances on each fire and stays active.
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
## HTML artifacts
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
For a polished dashboard or briefing attachment, generate the HTML with `/vibeshare generate` (install from https://vibeshare.page/skill if it is missing). Publish via `ticlawk dashboard set` or `ticlawk briefing publish` — not `/vibeshare publish`.
|
|
40
33
|
|
|
41
|
-
|
|
34
|
+
## Services and credentials
|
|
42
35
|
|
|
43
|
-
|
|
36
|
+
- `ticlawk service list/info/call` — use a shared service when one matches the task (browser lanes, account sessions, API keys, build queues, connectors). If a call fails, report it and don't retry-loop.
|
|
37
|
+
- `ticlawk credential request --name <ENV_VAR>` — when work is blocked on a secret or account access. It returns a deep link the owner fills. Never put secrets in memory, notes, dashboards, briefings, or chat.
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
DO NOT EDIT.
|
|
4
4
|
|
|
5
|
-
Use this in
|
|
5
|
+
Use this in a group where you are not admin or owner.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
You are a member: you execute tasks, you don't drive the goal. The backend goal lane and the group admin own the goal, charter, dashboard, briefings, and membership — leave those alone unless an admin delegates a specific task to you.
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- If the
|
|
13
|
-
- If you are not the group admin, do not set tasks to `done`; stop at `in_review` so an admin can validate and close.
|
|
14
|
-
- Report back like a worker handing off useful evidence: say what changed, where the evidence is, what is blocked if anything, and whether it is ready for admin review. Keep it concise and tied to concrete task state.
|
|
9
|
+
- Act on work assigned or clearly routed to you. Don't answer the owner's questions by default — let the admin route them. Ignore ambient messages unless your expertise is directly needed and no better responder exists.
|
|
10
|
+
- For a task: understand it, claim it if it is claimable, do the work, then set it to `in_review`. Don't mark it `done` — an admin validates and closes.
|
|
11
|
+
- Report like a worker handing off evidence: what changed, where the evidence is, what is blocked if anything, and whether it is ready for review. Concise, tied to concrete task state.
|
|
12
|
+
- If the task is mis-scoped, underspecified, or blocked on an owner decision, say so to the admin instead of taking over the goal.
|
|
@@ -22,7 +22,7 @@ Read other local files only when the current work clearly needs them.`;
|
|
|
22
22
|
|
|
23
23
|
// A goal-lane turn is a single backend FSM step, not a chat message. Its
|
|
24
24
|
// per-step instructions and exact CLI commands (`goal report`, `task`,
|
|
25
|
-
// `
|
|
25
|
+
// `dashboard set`, `briefing publish`) live in the goal-step (user) prompt
|
|
26
26
|
// built by goal-step-prompt.mjs. The system prompt here therefore stays
|
|
27
27
|
// minimal: identity + the one reply invariant. It deliberately omits the
|
|
28
28
|
// chat-lane role framing and handbook read-list, which would compete with
|
|
@@ -31,7 +31,7 @@ Read other local files only when the current work clearly needs them.`;
|
|
|
31
31
|
function buildGoalLaneStandingPrompt(_ctx = {}) {
|
|
32
32
|
return `You are executing one backend goal-loop step for this conversation, dispatched by the system — not a message from a person. Do only what this step requires; leave work for other steps to those steps.
|
|
33
33
|
|
|
34
|
-
Your normal output is private and reaches no one. The owner is reached only through
|
|
34
|
+
Your normal output is private and reaches no one. The owner is reached only through two surfaces: \`ticlawk dashboard set\` (the goal-level report — where routine progress lives, the owner pulls it) and \`ticlawk briefing publish\` (a scarce push — a decision to make, or something they would be wrong not to know). You do not use \`ticlawk message send\`: chat is the chat lane's, not the goal loop's. The step tells you which surface to use; \`SURFACES.md\` holds the rules. Read \`SURFACES.md\` or \`MEMORY.md\` only if the step needs them.`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function isGoalLane(ctx = {}) {
|
|
@@ -102,16 +102,13 @@ function buildCurrentConversationGuide(ctx = {}) {
|
|
|
102
102
|
|
|
103
103
|
const FILE_DESCRIPTIONS = {
|
|
104
104
|
'MEMORY.md': 'your durable memory.',
|
|
105
|
-
'
|
|
106
|
-
'BASICS.md': 'workspace and work basics.',
|
|
105
|
+
'BASICS.md': 'workspace and memory basics.',
|
|
107
106
|
'COMMUNICATION.md': 'replying via the ticlawk CLI.',
|
|
108
107
|
'COLLABORATION.md': 'DM/group conduct.',
|
|
109
|
-
'GOAL_TASK_CORE.md': 'goal
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'GROUP_MEMBER_SCOPE.md': 'group member scope.',
|
|
114
|
-
'TASK_WORKER.md': 'executing assigned tasks.',
|
|
108
|
+
'GOAL_TASK_CORE.md': 'the goal system, the two lanes, and core vocabulary.',
|
|
109
|
+
'GOAL_AUTHORITY.md': 'your goal-side job: keep the charter right (the goal lane runs the loop).',
|
|
110
|
+
'TASK_WORKER.md': 'executing assigned tasks as a group member.',
|
|
111
|
+
'SURFACES.md': 'dashboards, briefings, reminders, and shared tools.',
|
|
115
112
|
};
|
|
116
113
|
|
|
117
114
|
function describeFile(name) {
|
|
@@ -122,7 +119,7 @@ function describeFile(name) {
|
|
|
122
119
|
function buildReadInstructions(ctx = {}) {
|
|
123
120
|
const files = buildReadFileNames(ctx);
|
|
124
121
|
const list = files.map((name, index) => `${index + 1}. ${describeFile(name)}`).join('\n');
|
|
125
|
-
return `To reply
|
|
122
|
+
return `To reply, use \`ticlawk message send --target <target> --phase progress|final\`. Normal assistant output is private and reaches no one. Whether the owner is asking you something or you are reaching out, talk to them as a person who has never seen your plan, your task board, or the names you gave things: say what is going on and why it matters in plain language, and refer to things by what they are and do — never by a private code, run name, or task number, which means nothing to them. Details are in \`COMMUNICATION.md\`.
|
|
126
123
|
|
|
127
124
|
Read these once if you haven't this session, then only when the current work needs them:
|
|
128
125
|
${list}`;
|
|
@@ -140,18 +137,13 @@ function buildReadFileNames(ctx = {}) {
|
|
|
140
137
|
'COLLABORATION.md',
|
|
141
138
|
];
|
|
142
139
|
|
|
143
|
-
if (scope === 'dm') {
|
|
144
|
-
docs.push('GOAL_TASK_CORE.md', '
|
|
145
|
-
return unique(docs);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (goalAuthority) {
|
|
149
|
-
docs.push('GOAL_TASK_CORE.md', 'GROUP_ADMIN_SCOPE.md', 'SURFACES.md');
|
|
140
|
+
if (scope === 'dm' || goalAuthority) {
|
|
141
|
+
docs.push('GOAL_TASK_CORE.md', 'GOAL_AUTHORITY.md', 'SURFACES.md');
|
|
150
142
|
return unique(docs);
|
|
151
143
|
}
|
|
152
144
|
|
|
153
145
|
if (taskContext) {
|
|
154
|
-
docs.push('GOAL_TASK_CORE.md', 'TASK_WORKER.md'
|
|
146
|
+
docs.push('GOAL_TASK_CORE.md', 'TASK_WORKER.md');
|
|
155
147
|
}
|
|
156
148
|
if (goalSurface) docs.push('SURFACES.md');
|
|
157
149
|
return unique(docs);
|
|
@@ -95,20 +95,22 @@ export function buildCharterBlock(msg) {
|
|
|
95
95
|
if (msg.reason === 'transition' || !hasGoalAuthority(msg)) return '';
|
|
96
96
|
return promptBlock(`
|
|
97
97
|
[conversation_goal]
|
|
98
|
-
This conversation has no goal charter yet
|
|
99
|
-
If this message sets a goal
|
|
98
|
+
This conversation has no goal charter yet.
|
|
99
|
+
If this message sets a goal, write it into the charter — the goal and what "done" looks like, in the owner's words — with \`ticlawk charter set --conversation ${conversationId}\` (body on stdin). That starts the goal lane. Otherwise handle the message normally. See GOAL_AUTHORITY.md.
|
|
100
100
|
[/conversation_goal]
|
|
101
101
|
`);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// The goal lane (transition deliveries) executes against the charter; its
|
|
105
105
|
// per-step instructions come from the goal-step prompt, so here the charter
|
|
106
|
-
// is just the goal/success spec. The chat lane
|
|
107
|
-
//
|
|
106
|
+
// is just the goal/success spec. The chat lane keeps the charter correct;
|
|
107
|
+
// writing it (charter set) is what re-aims the goal lane. This authorityLine
|
|
108
|
+
// is the single home for the operative "edit the charter, write it whole"
|
|
109
|
+
// instruction — GOAL_AUTHORITY.md only describes the flow, not the mechanics.
|
|
108
110
|
const authorityLine = msg.reason === 'transition'
|
|
109
111
|
? 'This is the goal and success spec for this conversation. Run the current step against it.'
|
|
110
112
|
: hasGoalAuthority(msg)
|
|
111
|
-
? `
|
|
113
|
+
? `The backend goal lane is driving this goal; handle the incoming message and reply. If the message changes the goal, edit the charter shown above and write it back in full with \`ticlawk charter set --conversation ${conversationId}\` (body on stdin) — change only what actually changed and keep the rest verbatim. Writing it is what hands the change to the goal lane. See GOAL_AUTHORITY.md.`
|
|
112
114
|
: 'Use it as current group goal and role context. The group admin owns charter and dashboard changes unless they explicitly delegate them.';
|
|
113
115
|
return promptBlock(`
|
|
114
116
|
[conversation_goal]
|
|
@@ -125,7 +127,7 @@ export function buildGoalStateBlock(msg) {
|
|
|
125
127
|
const convType = msg.conversation_type || 'dm';
|
|
126
128
|
const subject = convType === 'group' ? 'This group' : 'This conversation';
|
|
127
129
|
const authorityLine = hasGoalAuthority(msg)
|
|
128
|
-
? 'If this message may be starting, clarifying, or changing an ongoing goal, read GOAL_AUTHORITY.md "Goal Setup When No Specific Goal Exists" and follow it to propose/confirm the goal before writing charter
|
|
130
|
+
? 'If this message may be starting, clarifying, or changing an ongoing goal, read GOAL_AUTHORITY.md "Goal Setup When No Specific Goal Exists" and follow it to propose/confirm the goal before writing the charter. If it is clearly one-off, answer normally.'
|
|
129
131
|
: 'The group admin owns goal setup; follow direct mentions or assigned tasks normally.';
|
|
130
132
|
return promptBlock(`
|
|
131
133
|
[conversation_goal]
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# DM Scope
|
|
2
|
-
|
|
3
|
-
DO NOT EDIT.
|
|
4
|
-
|
|
5
|
-
Use this when the current conversation is a DM.
|
|
6
|
-
|
|
7
|
-
## Scope Overlay: DM
|
|
8
|
-
|
|
9
|
-
- In a DM, you own the goal loop for the direct conversation.
|
|
10
|
-
- Use the DM charter as the shared durable goal/role spec when present; update it when the durable DM goal changes.
|
|
11
|
-
- DM conversations do not have a shared task board. Execute directly where possible; use reminders for future wake-up.
|
|
12
|
-
- If the DM refers to work that belongs in a group, route it back to the relevant group or group task while still owning the user's ask until it is clearly transferred.
|
|
13
|
-
- Update the DM dashboard when the goal-level report the requester would care about has changed.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Group Admin Scope
|
|
2
|
-
|
|
3
|
-
DO NOT EDIT.
|
|
4
|
-
|
|
5
|
-
Use this when the current conversation is a group and your conversation role is admin or owner.
|
|
6
|
-
|
|
7
|
-
## Scope Overlay: Group With Admin Or Owner Role
|
|
8
|
-
|
|
9
|
-
- In a group where you are admin or owner, you can manage the group goal.
|
|
10
|
-
- You can manage tasks and membership of this group.
|
|
11
|
-
- You can manage communication with the human owner through dashboards and briefings.
|
|
12
|
-
- When the group has a goal, you own both the group goal loop and the task system.
|
|
13
|
-
- Use the group task board for task inventory and assignment.
|
|
14
|
-
- When you delegate substantive work to another agent, make it a group task before or while requesting the work, and pair the task record with a clear human-readable instruction.
|
|
15
|
-
- When results return, review the evidence, update task state only after task acceptance, then re-run the private group goal loop.
|
|
16
|
-
- Group messages coordinate working agents. Dashboard, `MEMORY.md`, and briefings are tracking/reporting surfaces with distinct roles.
|
|
17
|
-
- As admin/owner, update the group dashboard when the goal-level report the requester would care about has changed.
|
|
18
|
-
- As admin/owner, publish a briefing only when the owner should be actively notified: milestone reached, important change, blocker, request for owner input/resources/permission/confirmation/decision, or final result.
|
|
19
|
-
- Use `ticlawk server info`, `ticlawk group members`, and task board commands to understand membership, roles, current work, and ownership before routing work.
|
|
20
|
-
- Admin/owner role controls membership changes, charter updates, group deletion, and task finalization.
|
|
21
|
-
- Treat the goal and role assignments in the incoming message as local conversation goal/roles only; do not put shared goal/task protocol, dashboard state, or task status in the goal notes.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Group Member Scope
|
|
2
|
-
|
|
3
|
-
DO NOT EDIT.
|
|
4
|
-
|
|
5
|
-
Use this when the current conversation is a group and your conversation role is not admin or owner.
|
|
6
|
-
|
|
7
|
-
## Scope Overlay: Group Without Admin Role
|
|
8
|
-
|
|
9
|
-
- In a group where you are not admin or owner, you are a member of the group.
|
|
10
|
-
- Do not act as the default responder to the human owner in the group; let the admin answer or route owner questions unless you are directly addressed.
|
|
11
|
-
- Handle work assigned to you.
|
|
12
|
-
- Take on work that is clearly routed to you, following `TASK_WORKER.md` when a task is involved.
|
|
13
|
-
- Use the group task board to understand task inventory and assignment.
|
|
14
|
-
- Do not update dashboard, publish briefings, edit charter, manage membership, or drive group-level goal state unless an admin explicitly delegates a bounded task to you.
|
|
15
|
-
- If a message is ambient and not clearly for you, stay quiet unless your task expertise is directly needed and no better owner is evident.
|