syntaur 0.69.0 → 0.71.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/.claude-plugin/plugin.json +1 -1
- package/dashboard/dist/assets/{_basePickBy-DKk6tHtk.js → _basePickBy-BfpzwNC3.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-DM-f7DWz.js → _baseUniq-wFEHBTCT.js} +1 -1
- package/dashboard/dist/assets/{arc-ZBlA3YdV.js → arc-Bdcw4sCg.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-BUmvtGTF.js → architectureDiagram-2XIMDMQ5-BessFAtJ.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-B3qxWK6s.js → blockDiagram-WCTKOSBZ-CmjyyZPp.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BEq_UJO-.js → c4Diagram-IC4MRINW-dT6p8cwc.js} +1 -1
- package/dashboard/dist/assets/channel-BOguQ5S4.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-C-Y9ryMm.js → chunk-4BX2VUAB-BlY-k8DY.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-CGdtbsjw.js → chunk-55IACEB6-CtQ0p0jb.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-DllxJhUp.js → chunk-FMBD7UC4-DEevt_Yh.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-jjMM8O5F.js → chunk-JSJVCQXG-CpjLL7Nh.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-B_6BPltQ.js → chunk-KX2RTZJC-BWNRms_o.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-D0hJiXHp.js → chunk-NQ4KR5QH-qo2zbylv.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-BCWo4hLS.js → chunk-QZHKN3VN-DRvojtzc.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-DH_jEAwg.js → chunk-WL4C6EOR-A40iPU5N.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-BLSHooma.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BLSHooma.js +1 -0
- package/dashboard/dist/assets/clone-iSEXw5tA.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-5ld00TOH.js → cose-bilkent-S5V4N54A-CYaO7nsk.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-Cnu6eQWy.js → dagre-KLK3FWXG-NX3inwVZ.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-_CBBKNP-.js → diagram-E7M64L7V-D9cJwhQW.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-DE6WjIb1.js → diagram-IFDJBPK2-Bo5sFrMg.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-DpW7UzNK.js → diagram-P4PSJMXO-DfRH0XU7.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-BD2409fE.js → erDiagram-INFDFZHY-BgP1bwgw.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-1p0khhFI.js → flowDiagram-PKNHOUZH-C8Wws1ci.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-B2zFyA4s.js → ganttDiagram-A5KZAMGK-BgJhUuj8.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-bH-4YH7h.js → gitGraphDiagram-K3NZZRJ6-CI9FgCgo.js} +1 -1
- package/dashboard/dist/assets/{graph-BT24B6iQ.js → graph-B_7GyeiA.js} +1 -1
- package/dashboard/dist/assets/{index-Cxqr3rQB.js → index-CbndxFlO.js} +3 -3
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-CMzP4Hcg.js → infoDiagram-LFFYTUFH-BEtZcRxI.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-DMEmFC7M.js → ishikawaDiagram-PHBUUO56-0o9Bksuc.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-CAtzYQUm.js → journeyDiagram-4ABVD52K-RyRU3as7.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-d1JVbtvX.js → kanban-definition-K7BYSVSG-hLrHHizB.js} +1 -1
- package/dashboard/dist/assets/{layout-BVuI38I_.js → layout-w458wydd.js} +1 -1
- package/dashboard/dist/assets/{linear-Bc8PGMbp.js → linear-CnRlR5_w.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-UtwFYLNj.js → mermaid.core-DJ_9ty0Y.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-DHc5RCDj.js → mindmap-definition-YRQLILUH-C7TIzJVC.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-9anIsdIA.js → pieDiagram-SKSYHLDU-BZ9ysteM.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-FZ0D9HnU.js → quadrantDiagram-337W2JSQ-DpaMVSO1.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-BkjCvH_u.js → requirementDiagram-Z7DCOOCP-EXFcskZZ.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DzqwYHDo.js → sankeyDiagram-WA2Y5GQK-BdImdXkY.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-BW4g5Ao-.js → sequenceDiagram-2WXFIKYE-CWN3faYf.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-D0tKU3Z0.js → stateDiagram-RAJIS63D-DIQdn-BF.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-1u62oWzq.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-Bu269QDX.js → timeline-definition-YZTLITO2-DMTIpUOE.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-BGu_rrva.js → treemap-KZPCXAKY-Y2AH2GB7.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-Cx_n5FRZ.js → vennDiagram-LZ73GAT5-BF4bJK-l.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-BOJsKV_W.js → xychartDiagram-JWTSCODW-DH-tOBC5.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/dashboard/server.js +1427 -550
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +2816 -1559
- package/dist/index.js.map +1 -1
- package/dist/launch/index.js +913 -141
- package/dist/launch/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
- package/platforms/claude-code/hooks/enforce-boundaries.sh +49 -16
- package/platforms/claude-code/hooks/session-cleanup.sh +4 -2
- package/platforms/claude-code/skills/add-memory/SKILL.md +3 -2
- package/platforms/claude-code/skills/add-resource/SKILL.md +3 -2
- package/platforms/claude-code/skills/bundle-worktree/SKILL.md +3 -3
- package/platforms/claude-code/skills/capture-artifacts/SKILL.md +2 -2
- package/platforms/claude-code/skills/claim-resource/SKILL.md +3 -3
- package/platforms/claude-code/skills/clear-assignment/SKILL.md +9 -27
- package/platforms/claude-code/skills/complete-assignment/SKILL.md +3 -3
- package/platforms/claude-code/skills/create-assignment/SKILL.md +2 -2
- package/platforms/claude-code/skills/extend-resource/SKILL.md +2 -2
- package/platforms/claude-code/skills/grab-assignment/SKILL.md +17 -12
- package/platforms/claude-code/skills/grab-bundle/SKILL.md +10 -6
- package/platforms/claude-code/skills/log-progress/SKILL.md +6 -4
- package/platforms/claude-code/skills/plan-assignment/SKILL.md +3 -3
- package/platforms/claude-code/skills/plan-bundle/SKILL.md +4 -3
- package/platforms/claude-code/skills/replan/SKILL.md +9 -6
- package/platforms/claude-code/skills/resume-session/SKILL.md +14 -8
- package/platforms/claude-code/skills/save-session-summary/SKILL.md +4 -4
- package/platforms/claude-code/skills/set-workspace/SKILL.md +9 -6
- package/platforms/claude-code/skills/syntaur-protocol/SKILL.md +9 -7
- package/platforms/claude-code/skills/syntaur-protocol/references/file-ownership.md +1 -1
- package/platforms/claude-code/skills/syntaur-worktree/SKILL.md +11 -7
- package/platforms/codex/.codex-plugin/plugin.json +1 -1
- package/platforms/codex/scripts/enforce-boundaries.sh +74 -12
- package/platforms/codex/scripts/session-cleanup.sh +20 -13
- package/platforms/codex/skills/add-memory/SKILL.md +3 -2
- package/platforms/codex/skills/add-resource/SKILL.md +3 -2
- package/platforms/codex/skills/bundle-worktree/SKILL.md +3 -3
- package/platforms/codex/skills/capture-artifacts/SKILL.md +2 -2
- package/platforms/codex/skills/claim-resource/SKILL.md +3 -3
- package/platforms/codex/skills/clear-assignment/SKILL.md +9 -27
- package/platforms/codex/skills/complete-assignment/SKILL.md +3 -3
- package/platforms/codex/skills/create-assignment/SKILL.md +2 -2
- package/platforms/codex/skills/extend-resource/SKILL.md +2 -2
- package/platforms/codex/skills/grab-assignment/SKILL.md +17 -12
- package/platforms/codex/skills/grab-bundle/SKILL.md +10 -6
- package/platforms/codex/skills/log-progress/SKILL.md +6 -4
- package/platforms/codex/skills/plan-assignment/SKILL.md +3 -3
- package/platforms/codex/skills/plan-bundle/SKILL.md +4 -3
- package/platforms/codex/skills/replan/SKILL.md +9 -6
- package/platforms/codex/skills/resume-session/SKILL.md +14 -8
- package/platforms/codex/skills/save-session-summary/SKILL.md +4 -4
- package/platforms/codex/skills/set-workspace/SKILL.md +9 -6
- package/platforms/codex/skills/syntaur-protocol/SKILL.md +9 -7
- package/platforms/codex/skills/syntaur-protocol/references/file-ownership.md +1 -1
- package/platforms/codex/skills/syntaur-worktree/SKILL.md +11 -7
- package/platforms/hermes/plugins/syntaur/__init__.py +29 -3
- package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/boundary.py +18 -9
- package/platforms/pi/extensions/syntaur/index.ts +84 -29
- package/skills/add-memory/SKILL.md +3 -2
- package/skills/add-resource/SKILL.md +3 -2
- package/skills/bundle-worktree/SKILL.md +3 -3
- package/skills/capture-artifacts/SKILL.md +2 -2
- package/skills/claim-resource/SKILL.md +3 -3
- package/skills/clear-assignment/SKILL.md +9 -27
- package/skills/complete-assignment/SKILL.md +3 -3
- package/skills/create-assignment/SKILL.md +2 -2
- package/skills/extend-resource/SKILL.md +2 -2
- package/skills/grab-assignment/SKILL.md +17 -12
- package/skills/grab-bundle/SKILL.md +10 -6
- package/skills/log-progress/SKILL.md +6 -4
- package/skills/plan-assignment/SKILL.md +3 -3
- package/skills/plan-bundle/SKILL.md +4 -3
- package/skills/replan/SKILL.md +9 -6
- package/skills/resume-session/SKILL.md +14 -8
- package/skills/save-session-summary/SKILL.md +4 -4
- package/skills/set-workspace/SKILL.md +9 -6
- package/skills/syntaur-protocol/SKILL.md +9 -7
- package/skills/syntaur-protocol/references/file-ownership.md +1 -1
- package/skills/syntaur-worktree/SKILL.md +11 -7
- package/dashboard/dist/assets/channel-fypxffzQ.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-1KnjQvtL.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-1KnjQvtL.js +0 -1
- package/dashboard/dist/assets/clone-CKMabBhS.js +0 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DxWQhjNO.js +0 -1
package/package.json
CHANGED
|
@@ -56,25 +56,50 @@ if [ -z "$FILE_PATH" ]; then
|
|
|
56
56
|
fi
|
|
57
57
|
|
|
58
58
|
# --- Step 7: Check for context file ---
|
|
59
|
+
# context.json is a WORKSPACE MARKER. Its mere presence means "this workspace is
|
|
60
|
+
# under Syntaur enforcement"; its absence means "not a Syntaur workspace → allow".
|
|
59
61
|
CONTEXT_FILE=".syntaur/context.json"
|
|
60
62
|
if [ ! -f "$CONTEXT_FILE" ]; then
|
|
61
|
-
# No
|
|
63
|
+
# No Syntaur workspace; allow all writes (unchanged behavior).
|
|
62
64
|
allow_and_exit
|
|
63
65
|
fi
|
|
64
66
|
|
|
65
|
-
# --- Step 8:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
# --- Step 8: Resolve the write boundary from the session's OPEN engagement ---
|
|
68
|
+
# The assignment scalars were demoted out of context.json — the active assignment
|
|
69
|
+
# now lives on the session's engagement. Ask the CLI to resolve it. Parse the
|
|
70
|
+
# PreToolUse stdin payload for the calling session id and pass it explicitly so
|
|
71
|
+
# co-tenant clobbering can't misattribute. If the CLI is unavailable or resolves
|
|
72
|
+
# nothing, ASSIGNMENT_DIR/MISSION_DIR stay empty → we enforce WORKSPACE-ONLY
|
|
73
|
+
# below (we do NOT fail open).
|
|
74
|
+
ASSIGNMENT_DIR=""
|
|
75
|
+
MISSION_DIR=""
|
|
76
|
+
WORKSPACE_ROOT=""
|
|
77
|
+
|
|
78
|
+
# The cwd holding this context file (its parent's parent: ".syntaur/context.json").
|
|
79
|
+
CONTEXT_DIR="$(cd "$(dirname "$CONTEXT_FILE")/.." 2>/dev/null && pwd)"
|
|
80
|
+
[ -z "$CONTEXT_DIR" ] && CONTEXT_DIR="$(pwd)"
|
|
81
|
+
|
|
82
|
+
SID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
83
|
+
|
|
84
|
+
if command -v syntaur >/dev/null 2>&1; then
|
|
85
|
+
BOUNDARY_JSON=$(cd "$CONTEXT_DIR" 2>/dev/null && \
|
|
86
|
+
syntaur session boundary --json ${SID:+--session-id "$SID"} 2>/dev/null)
|
|
87
|
+
if [ -n "$BOUNDARY_JSON" ]; then
|
|
88
|
+
ASSIGNMENT_DIR=$(echo "$BOUNDARY_JSON" | jq -r '.assignmentDir // empty' 2>/dev/null)
|
|
89
|
+
MISSION_DIR=$(echo "$BOUNDARY_JSON" | jq -r '.projectDir // empty' 2>/dev/null)
|
|
90
|
+
WORKSPACE_ROOT=$(echo "$BOUNDARY_JSON" | jq -r '.workspaceRoot // empty' 2>/dev/null)
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
69
93
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
# Fall back to the context.json workspace marker if the CLI did not surface one
|
|
95
|
+
# (e.g. standalone session with a worktree but no engagement yet).
|
|
96
|
+
if [ -z "$WORKSPACE_ROOT" ]; then
|
|
97
|
+
WORKSPACE_ROOT=$(jq -r '.workspaceRoot // empty' "$CONTEXT_FILE" 2>/dev/null)
|
|
73
98
|
fi
|
|
74
99
|
|
|
75
|
-
# --- Step 9: Expand ~ in paths ---
|
|
76
|
-
ASSIGNMENT_DIR="${ASSIGNMENT_DIR/#\~/$HOME}"
|
|
77
|
-
MISSION_DIR="${MISSION_DIR/#\~/$HOME}"
|
|
100
|
+
# --- Step 9: Expand ~ in paths (guarding empties) ---
|
|
101
|
+
[ -n "$ASSIGNMENT_DIR" ] && ASSIGNMENT_DIR="${ASSIGNMENT_DIR/#\~/$HOME}"
|
|
102
|
+
[ -n "$MISSION_DIR" ] && MISSION_DIR="${MISSION_DIR/#\~/$HOME}"
|
|
78
103
|
if [ -n "$WORKSPACE_ROOT" ] && [ "$WORKSPACE_ROOT" != "null" ]; then
|
|
79
104
|
WORKSPACE_ROOT="${WORKSPACE_ROOT/#\~/$HOME}"
|
|
80
105
|
else
|
|
@@ -82,14 +107,18 @@ else
|
|
|
82
107
|
fi
|
|
83
108
|
|
|
84
109
|
# --- Step 10: Check allowed paths ---
|
|
110
|
+
# NOTE: every prefix test is guarded by a non-empty check so an EMPTY $DIR never
|
|
111
|
+
# globs to "/*" and silently allows the whole filesystem. When no assignment
|
|
112
|
+
# resolves, only the workspace-root (and context file) checks can match → this is
|
|
113
|
+
# WORKSPACE-ONLY enforcement, NOT fail-open.
|
|
85
114
|
|
|
86
115
|
# Allow: files inside the assignment directory
|
|
87
|
-
if [[ "$FILE_PATH" == "$ASSIGNMENT_DIR"/* ]]; then
|
|
116
|
+
if [ -n "$ASSIGNMENT_DIR" ] && [[ "$FILE_PATH" == "$ASSIGNMENT_DIR"/* ]]; then
|
|
88
117
|
allow_and_exit
|
|
89
118
|
fi
|
|
90
119
|
|
|
91
120
|
# Allow: files in project resources/ directory (but NOT derived _index.md)
|
|
92
|
-
if [[ "$FILE_PATH" == "$MISSION_DIR/resources/"* ]]; then
|
|
121
|
+
if [ -n "$MISSION_DIR" ] && [[ "$FILE_PATH" == "$MISSION_DIR/resources/"* ]]; then
|
|
93
122
|
BASENAME=$(basename "$FILE_PATH")
|
|
94
123
|
if [[ "$BASENAME" == _* ]]; then
|
|
95
124
|
# Derived file (e.g., _index.md) -- fall through to block
|
|
@@ -100,7 +129,7 @@ if [[ "$FILE_PATH" == "$MISSION_DIR/resources/"* ]]; then
|
|
|
100
129
|
fi
|
|
101
130
|
|
|
102
131
|
# Allow: files in project memories/ directory (but NOT derived _index.md)
|
|
103
|
-
if [[ "$FILE_PATH" == "$MISSION_DIR/memories/"* ]]; then
|
|
132
|
+
if [ -n "$MISSION_DIR" ] && [[ "$FILE_PATH" == "$MISSION_DIR/memories/"* ]]; then
|
|
104
133
|
BASENAME=$(basename "$FILE_PATH")
|
|
105
134
|
if [[ "$BASENAME" == _* ]]; then
|
|
106
135
|
# Derived file (e.g., _index.md) -- fall through to block
|
|
@@ -112,7 +141,7 @@ fi
|
|
|
112
141
|
|
|
113
142
|
# Allow: the context file itself
|
|
114
143
|
CONTEXT_ABS="$(cd "$(dirname "$CONTEXT_FILE")" 2>/dev/null && echo "$(pwd)/$(basename "$CONTEXT_FILE")")"
|
|
115
|
-
if [ "$FILE_PATH" = "$CONTEXT_ABS" ]; then
|
|
144
|
+
if [ -n "$CONTEXT_ABS" ] && [ "$FILE_PATH" = "$CONTEXT_ABS" ]; then
|
|
116
145
|
allow_and_exit
|
|
117
146
|
fi
|
|
118
147
|
|
|
@@ -122,7 +151,11 @@ if [ -n "$WORKSPACE_ROOT" ] && [[ "$FILE_PATH" == "$WORKSPACE_ROOT"/* ]]; then
|
|
|
122
151
|
fi
|
|
123
152
|
|
|
124
153
|
# --- Step 11: Block the write ---
|
|
125
|
-
|
|
154
|
+
if [ -n "$ASSIGNMENT_DIR" ]; then
|
|
155
|
+
REASON="Syntaur write boundary violation: Cannot write to '$FILE_PATH'. Allowed paths: assignment dir ($ASSIGNMENT_DIR), project resources/memories${MISSION_DIR:+ ($MISSION_DIR)}, workspace (${WORKSPACE_ROOT:-none})."
|
|
156
|
+
else
|
|
157
|
+
REASON="Syntaur write boundary violation: Cannot write to '$FILE_PATH'. No active assignment for this session — writes are restricted to the workspace (${WORKSPACE_ROOT:-none}). Run /grab-assignment to bind an assignment and widen the boundary."
|
|
158
|
+
fi
|
|
126
159
|
|
|
127
160
|
# Escape for JSON
|
|
128
161
|
REASON_ESCAPED=$(echo "$REASON" | jq -Rs '.' 2>/dev/null)
|
|
@@ -34,12 +34,14 @@ syntaur_bounded_stop || true
|
|
|
34
34
|
# after the agent walks away. Best-effort, bounded (~3s, no `timeout` on macOS),
|
|
35
35
|
# and migration-gated (`--if-migrated`) so it can't re-derive pre-migration
|
|
36
36
|
# assignments during rollout. Resolves the assignment from the ending session's
|
|
37
|
-
#
|
|
37
|
+
# latest engagement (passed via --session-id); no-ops silently when none.
|
|
38
38
|
HOOK_CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
|
|
39
|
+
HOOK_SID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
39
40
|
syntaur_bounded_recompute() {
|
|
40
41
|
local cpid kpid rc
|
|
41
42
|
[ -n "$HOOK_CWD" ] && [ -f "$HOOK_CWD/.syntaur/context.json" ] || return 0
|
|
42
|
-
( cd "$HOOK_CWD" 2>/dev/null &&
|
|
43
|
+
( cd "$HOOK_CWD" 2>/dev/null && \
|
|
44
|
+
syntaur recompute --if-migrated ${HOOK_SID:+--session-id "$HOOK_SID"} >/dev/null 2>&1 ) &
|
|
43
45
|
cpid=$!
|
|
44
46
|
( sleep 3; kill -KILL "$cpid" 2>/dev/null ) >/dev/null 2>&1 &
|
|
45
47
|
kpid=$!
|
|
@@ -32,8 +32,9 @@ file-ownership protocol.
|
|
|
32
32
|
|
|
33
33
|
## Step 1: Resolve project
|
|
34
34
|
|
|
35
|
-
If
|
|
36
|
-
|
|
35
|
+
If the session has an open engagement with an active assignment (`syntaur
|
|
36
|
+
session resume --json`), default to its `projectSlug`. Otherwise ask the user
|
|
37
|
+
which project to add the memory to.
|
|
37
38
|
|
|
38
39
|
## Step 2: Gather inputs
|
|
39
40
|
|
|
@@ -30,8 +30,9 @@ CLI-managed file per the file-ownership protocol).
|
|
|
30
30
|
|
|
31
31
|
## Step 1: Resolve project
|
|
32
32
|
|
|
33
|
-
If
|
|
34
|
-
|
|
33
|
+
If the session has an open engagement with an active assignment (`syntaur
|
|
34
|
+
session resume --json`), default to its `projectSlug`. Otherwise ask the user
|
|
35
|
+
which project to add the resource to.
|
|
35
36
|
|
|
36
37
|
## Step 2: Gather inputs
|
|
37
38
|
|
|
@@ -45,9 +45,9 @@ The computed worktree path is **always**
|
|
|
45
45
|
|
|
46
46
|
## Step 2: Pre-flight
|
|
47
47
|
|
|
48
|
-
- Confirm `.syntaur/context.json` is a bundle context (has `bundleId
|
|
49
|
-
|
|
50
|
-
user to `/grab-bundle <id>` first.
|
|
48
|
+
- Confirm `.syntaur/context.json` is a bundle context (has `bundleId`). If the
|
|
49
|
+
session is instead bound to an assignment (an open engagement) with no
|
|
50
|
+
`bundleId`, stop and tell the user to `/grab-bundle <id>` first.
|
|
51
51
|
- Confirm `<repository>/.git` exists.
|
|
52
52
|
- Confirm the branch does NOT already exist. If it does, the CLI will
|
|
53
53
|
surface a `GitWorktreeError` — surface that verbatim.
|
|
@@ -17,7 +17,7 @@ Attach proof to your work. Reviewers should be able to scroll a single page (`pr
|
|
|
17
17
|
|
|
18
18
|
## Input
|
|
19
19
|
|
|
20
|
-
No arguments.
|
|
20
|
+
No arguments. The active assignment is resolved from the session's open engagement (`.syntaur/context.json` is only a workspace marker, not the assignment source).
|
|
21
21
|
|
|
22
22
|
## Step 1: Decide whether to capture
|
|
23
23
|
|
|
@@ -60,7 +60,7 @@ Rules:
|
|
|
60
60
|
- All other kinds (`screenshot`, `video`, `asciinema`) require `--file`. The CLI rejects nonexistent / non-file paths.
|
|
61
61
|
- `--criterion <index>` is optional — pass the **0-based** index into the `## Acceptance Criteria` checklist when you want to anchor the artifact to a specific criterion.
|
|
62
62
|
- `--transcribe` is video-only and writes a sibling `<id>.transcript.md` (requires `ELEVENLABS_API_KEY` + `ffmpeg`). `proof build` renders the transcript next to the player; clicking a phrase seeks the video.
|
|
63
|
-
- If
|
|
63
|
+
- If this session has an open engagement (active assignment), the positional target argument is unnecessary — the CLI resolves the target from the engagement. Otherwise pass `--project <slug> <assignment-slug>` or a bare assignment UUID.
|
|
64
64
|
|
|
65
65
|
The CLI copies the file (if any) under `<assignmentDir>/proof/<criterion|untagged>/<id>.<ext>` and inserts a row in `~/.syntaur/syntaur.db`. Output prints the artifact id and absolute path.
|
|
66
66
|
|
|
@@ -29,15 +29,15 @@ Examples:
|
|
|
29
29
|
|
|
30
30
|
Extract `<inventory_slug>` (required, first positional), plus optional `--ttl <duration>` and `--for <tag>`.
|
|
31
31
|
|
|
32
|
-
### Step 2: Pre-check
|
|
32
|
+
### Step 2: Pre-check workspace context
|
|
33
33
|
|
|
34
|
-
Read `.syntaur/context.json` from the current working directory. If the file is missing, OR
|
|
34
|
+
Read `.syntaur/context.json` (a workspace marker) from the current working directory. If the file is missing, OR carries no workspace markers (`repository`/`branch`/`worktreePath`/`workspaceRoot`) and no `sessionId`, abort with:
|
|
35
35
|
|
|
36
36
|
> "No active Syntaur context in this workspace. Grab an assignment first (`/grab-assignment <project> <slug>`) or restart the session so the SessionStart hook can populate `.syntaur/context.json`."
|
|
37
37
|
|
|
38
38
|
This guard exists because writing a leases-only context file would trip `syntaur doctor`'s workspace check.
|
|
39
39
|
|
|
40
|
-
If `--for` was not provided, derive its value from the
|
|
40
|
+
If `--for` was not provided, derive its value: prefer the active assignment's slug from the session's open engagement (`syntaur session resume --json`); otherwise fall back to the `sessionId` from the workspace marker.
|
|
41
41
|
|
|
42
42
|
### Step 3: Run the claim CLI
|
|
43
43
|
|
|
@@ -14,7 +14,7 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
# Clear Assignment
|
|
16
16
|
|
|
17
|
-
Drop the active assignment binding from the current
|
|
17
|
+
Drop the active assignment binding from the current session. The assignment itself is left untouched in `~/.syntaur/projects/.../assignments/` — only the session's open engagement (the binding that makes it the active assignment) is closed so the session is no longer scoped to it. `.syntaur/context.json` is a workspace marker and is not the binding — it does not hold the active assignment.
|
|
18
18
|
|
|
19
19
|
This is the inverse of `grab-assignment`. Unlike `complete-assignment`, it does **not** transition lifecycle state, write a handoff, or close out the work. Use it when:
|
|
20
20
|
|
|
@@ -28,17 +28,15 @@ If the assignment is actually done, use `complete-assignment` instead so a hando
|
|
|
28
28
|
|
|
29
29
|
Optional flags from the user:
|
|
30
30
|
|
|
31
|
-
- `--
|
|
32
|
-
- `--unassign` — also run `syntaur unassign <slug> --project <project>` so the assignment is no longer claimed by this agent. Default: leave the claim in place (only the local context is cleared).
|
|
31
|
+
- `--unassign` — also run `syntaur unassign <slug> --project <project>` so the assignment is no longer claimed by this agent. Default: leave the claim in place (only the session's engagement is closed).
|
|
33
32
|
|
|
34
33
|
## Step 1: Load Context
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
|
|
37
36
|
|
|
38
|
-
- If
|
|
39
|
-
- If the file exists but contains only session fields (`sessionId`, `transcriptPath`) and no `projectSlug` / `assignmentSlug`, tell the user: "No active assignment is bound — only a platform session record exists. Nothing to clear." and stop (unless they explicitly ask to wipe the session record too).
|
|
37
|
+
- If there is no open engagement, tell the user: "No active assignment is bound to this session — nothing to clear." and stop. (`.syntaur/context.json` is only a workspace marker; its presence does not mean an assignment is bound.)
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
From the resolved engagement, note: `projectSlug`, `assignmentSlug`, `assignmentDir`, `title`.
|
|
42
40
|
|
|
43
41
|
## Step 2: Confirm with the User
|
|
44
42
|
|
|
@@ -68,29 +66,15 @@ For standalone assignments use the UUID (the folder name) in place of the slug,
|
|
|
68
66
|
|
|
69
67
|
`syntaur unassign` clears the assignee on the assignment frontmatter (the inverse of `assign`) and bumps `updated`.
|
|
70
68
|
|
|
71
|
-
## Step 4:
|
|
69
|
+
## Step 4: Close the Engagement
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
Closing the session's open engagement is what drops the active-assignment binding — that is the operation that "clears" the assignment. The dashboard status PATCH in Step 5 (to `cleared`) closes the open engagement for a live session.
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
rm .syntaur/context.json
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
If the user passed `--keep-session`, preserve session fields and strip everything else instead:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
jq '{sessionId, transcriptPath} | with_entries(select(.value != null))' \
|
|
83
|
-
.syntaur/context.json > .syntaur/context.json.tmp \
|
|
84
|
-
&& mv .syntaur/context.json.tmp .syntaur/context.json
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
If the resulting file would be empty (`{}`), delete it instead of leaving an empty stub.
|
|
88
|
-
|
|
89
|
-
Do not delete the `.syntaur/` directory itself — other tooling may use it.
|
|
73
|
+
Do NOT delete or rewrite `.syntaur/context.json` to clear the assignment — it is a workspace marker and no longer carries the active assignment. Leave its repository/branch/worktree, session, and lease fields intact so other tooling keeps recognizing the workspace. Do not delete the `.syntaur/` directory.
|
|
90
74
|
|
|
91
75
|
## Step 5: Close Session (optional)
|
|
92
76
|
|
|
93
|
-
If the Syntaur dashboard is running, mark this session as cleared so the dashboard does not keep showing it as active. Resolve `<session-id>` from *your* running process — prefer `$CLAUDE_CODE_SESSION_ID` (or the peer `OPENCODE_SESSION_ID` / `PI_SESSION_ID`), otherwise run `syntaur session resolve-id`. Only if neither yields an id, fall back to the `sessionId`
|
|
77
|
+
If the Syntaur dashboard is running, mark this session as cleared so the dashboard does not keep showing it as active (this also closes the session's open engagement). Resolve `<session-id>` from *your* running process — prefer `$CLAUDE_CODE_SESSION_ID` (or the peer `OPENCODE_SESSION_ID` / `PI_SESSION_ID`), otherwise run `syntaur session resolve-id`. Only if neither yields an id, fall back to the legacy `sessionId` scalar in `.syntaur/context.json` — that scalar is a shared, legacy hint a co-tenant can clobber, so don't treat it as authoritative:
|
|
94
78
|
|
|
95
79
|
```bash
|
|
96
80
|
curl -s -X PATCH "http://localhost:$(cat ~/.syntaur/dashboard-port 2>/dev/null || echo 4800)/api/agent-sessions/<session-id>/status" \
|
|
@@ -100,8 +84,6 @@ curl -s -X PATCH "http://localhost:$(cat ~/.syntaur/dashboard-port 2>/dev/null |
|
|
|
100
84
|
|
|
101
85
|
If this fails (e.g., dashboard not running, endpoint not present in the installed version), it is non-critical — silently continue.
|
|
102
86
|
|
|
103
|
-
Skip this step entirely when `--keep-session` is set.
|
|
104
|
-
|
|
105
87
|
## Step 6: Report to User
|
|
106
88
|
|
|
107
89
|
Summarize:
|
|
@@ -19,11 +19,11 @@ Optional: the user may pass `--complete` to transition directly to `completed` i
|
|
|
19
19
|
|
|
20
20
|
## Step 1: Load Context
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
|
|
23
23
|
|
|
24
|
-
If
|
|
24
|
+
If there is no open engagement (no active assignment), tell the user: "No active assignment for this session — grab one first." `.syntaur/context.json` is only a workspace marker; do not read the assignment from it.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
From the resolved engagement, note: `projectSlug`, `assignmentSlug`, `assignmentDir`, `projectDir`.
|
|
27
27
|
|
|
28
28
|
## Step 2: Load Playbooks
|
|
29
29
|
|
|
@@ -30,9 +30,9 @@ Expects arguments from the user:
|
|
|
30
30
|
|
|
31
31
|
If no title was provided, ask the user what the assignment should be called.
|
|
32
32
|
|
|
33
|
-
If neither `--project` nor `--one-off` was provided, check
|
|
33
|
+
If neither `--project` nor `--one-off` was provided, check for an active assignment via the session's open engagement (`syntaur session resume --json`). If there is one, default `--project` to its `projectSlug` and confirm with the user: "Add this assignment to project `<projectSlug>`?"
|
|
34
34
|
|
|
35
|
-
If no
|
|
35
|
+
If there is no open engagement and no project flag, ask the user which project to add it to, or whether it should be a one-off.
|
|
36
36
|
|
|
37
37
|
## Step 1: Run the CLI
|
|
38
38
|
|
|
@@ -25,9 +25,9 @@ Examples:
|
|
|
25
25
|
|
|
26
26
|
Extract `<lease_id>` (first positional) and `--ttl <duration>` (required). If either is missing, abort with a usage message and a hint to call `/list-resources` to see active leases.
|
|
27
27
|
|
|
28
|
-
### Step 2: Pre-check
|
|
28
|
+
### Step 2: Pre-check workspace context
|
|
29
29
|
|
|
30
|
-
Read `.syntaur/context.json` from the current working directory. If the file is missing, OR
|
|
30
|
+
Read `.syntaur/context.json` (a workspace marker) from the current working directory. If the file is missing, OR carries no workspace markers (`repository`/`branch`/`worktreePath`/`workspaceRoot`) and no `sessionId`, abort with:
|
|
31
31
|
|
|
32
32
|
> "No active Syntaur context in this workspace. Grab an assignment first (`/grab-assignment <project> <slug>`) or restart the session so the SessionStart hook can populate `.syntaur/context.json`."
|
|
33
33
|
|
|
@@ -23,10 +23,16 @@ Expects up to two arguments from the user:
|
|
|
23
23
|
|
|
24
24
|
## Pre-flight Check
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
`.syntaur/context.json` is a WORKSPACE MARKER (repository/branch/worktree/workspaceRoot plus legacy session and bundle fields) — it is NOT the active-assignment source of truth. The active assignment binds via the session's open engagement (established by `track-session` in Step 6).
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
Check whether this session already has an open engagement — i.e., a different assignment is already active:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
syntaur session resume --json 2>/dev/null
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- If it reports an active assignment, warn the user: "You already have an active assignment: `<assignmentSlug>` in project `<projectSlug>`. Grabbing a new one will rebind this session. Proceed?" — stop if the user says no.
|
|
35
|
+
- If there is no open engagement (no active assignment), proceed. A `.syntaur/context.json` that holds only workspace-marker / session fields is expected — it does not represent an active assignment.
|
|
30
36
|
|
|
31
37
|
## Step 1: Discover the Project (project-nested path)
|
|
32
38
|
|
|
@@ -75,25 +81,24 @@ From the assignment frontmatter extract: `title`, `workspace.repository`, `works
|
|
|
75
81
|
|
|
76
82
|
If `workspace.repository` and `workspace.worktreePath` are both null, set them to the current working directory. Write boundaries use this path, so it must never be null while an agent is writing code.
|
|
77
83
|
|
|
78
|
-
## Step 5: Create or Merge
|
|
84
|
+
## Step 5: Create or Merge the Workspace Marker
|
|
79
85
|
|
|
80
|
-
|
|
86
|
+
`.syntaur/context.json` is a WORKSPACE MARKER — it records the repository/branch/worktree so tooling can recognize this directory as a Syntaur workspace. It is NOT the active-assignment source of truth: the assignment binds via the session's open engagement (Step 6, `track-session`). Do NOT write `projectSlug` / `assignmentSlug` / `assignmentDir` / `projectDir` / `title` — those scalars are non-authoritative.
|
|
87
|
+
|
|
88
|
+
Merge workspace markers into `.syntaur/context.json`. Never overwrite — if the file already exists (e.g., platform SessionStart hook populated `sessionId` / `transcriptPath`, or a worktree skill wrote bundle/lease fields), preserve those fields.
|
|
81
89
|
|
|
82
90
|
```bash
|
|
83
91
|
mkdir -p .syntaur
|
|
84
92
|
```
|
|
85
93
|
|
|
86
|
-
Prepare the
|
|
94
|
+
Prepare the workspace-marker payload:
|
|
87
95
|
|
|
88
96
|
```json
|
|
89
97
|
{
|
|
90
|
-
"
|
|
91
|
-
"assignmentSlug": "<assignment-slug>",
|
|
92
|
-
"projectDir": "/absolute/path/to/project or null",
|
|
93
|
-
"assignmentDir": "/absolute/path/to/assignment",
|
|
94
|
-
"workspaceRoot": "<workspace path or current working directory>",
|
|
95
|
-
"title": "<assignment title>",
|
|
98
|
+
"repository": "<workspace.repository or null>",
|
|
96
99
|
"branch": "<workspace.branch or null>",
|
|
100
|
+
"worktreePath": "<workspace.worktreePath or null>",
|
|
101
|
+
"workspaceRoot": "<workspace path or current working directory>",
|
|
97
102
|
"grabbedAt": "<ISO 8601 timestamp>"
|
|
98
103
|
}
|
|
99
104
|
```
|
|
@@ -34,16 +34,20 @@ the user to pick.
|
|
|
34
34
|
|
|
35
35
|
## Pre-flight check
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
First check whether this session already has an active assignment via its open
|
|
38
|
+
engagement (`syntaur session resume --json`):
|
|
39
|
+
|
|
40
|
+
- If it reports an active assignment, warn the user: "You already have an active
|
|
41
|
+
assignment. Grabbing a bundle will rebind this session. Proceed?" — stop if no.
|
|
42
|
+
|
|
43
|
+
Then read `.syntaur/context.json` (a workspace marker) in the current working
|
|
44
|
+
directory for bundle bookkeeping:
|
|
38
45
|
|
|
39
|
-
- If it already contains assignment fields (`projectSlug`/`assignmentSlug`/
|
|
40
|
-
`assignmentDir`), warn the user: "You already have an active assignment.
|
|
41
|
-
Grabbing a bundle will replace this context. Proceed?" — stop if no.
|
|
42
46
|
- If it already contains different bundle fields (`bundleId` set to a
|
|
43
47
|
different id), warn: "Context is bound to bundle b:<old>. Switch to b:<new>?"
|
|
44
48
|
— stop if no.
|
|
45
|
-
-
|
|
46
|
-
and merge bundle fields on top.
|
|
49
|
+
- A context.json holding only workspace-marker / `sessionId` fields is expected;
|
|
50
|
+
proceed and merge bundle fields on top.
|
|
47
51
|
|
|
48
52
|
## Step 1: Load the bundle
|
|
49
53
|
|
|
@@ -39,9 +39,11 @@ records current in real-time, especially after every meaningful action.
|
|
|
39
39
|
|
|
40
40
|
## Step 1: Verify there is an active assignment
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
`
|
|
44
|
-
|
|
42
|
+
The active assignment is resolved from the session's open engagement — `syntaur
|
|
43
|
+
progress log` (Step 3) targets it automatically. `.syntaur/context.json` is only
|
|
44
|
+
a workspace marker; do not read the assignment from it. If there is no open
|
|
45
|
+
engagement (no active assignment), the CLI aborts with "No active assignment for
|
|
46
|
+
this session — grab one first." Run `grab-assignment` first.
|
|
45
47
|
|
|
46
48
|
## Step 2: Compose the entry
|
|
47
49
|
|
|
@@ -69,7 +71,7 @@ Run:
|
|
|
69
71
|
syntaur progress log "<your composed entry body>"
|
|
70
72
|
```
|
|
71
73
|
|
|
72
|
-
The command resolves the active assignment from
|
|
74
|
+
The command resolves the active assignment from the session's open engagement
|
|
73
75
|
(or pass `--assignment <slug> [--project <slug>]` to target one explicitly),
|
|
74
76
|
then atomically:
|
|
75
77
|
|
|
@@ -20,14 +20,14 @@ Optional: the user may provide focus areas or notes to guide the plan.
|
|
|
20
20
|
|
|
21
21
|
## Step 1: Load Context
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it. If there is no open engagement (no active assignment), tell the user: "No active assignment for this session — grab one first." and stop. `.syntaur/context.json` is only a workspace marker; do not read the assignment from it.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
From the resolved engagement, note:
|
|
26
26
|
- `projectSlug` — the project slug (`null` for standalone assignments)
|
|
27
27
|
- `assignmentSlug` — the assignment slug
|
|
28
28
|
- `assignmentDir` — absolute path to the assignment folder
|
|
29
29
|
- `projectDir` — absolute path to the project folder (may be null for standalone)
|
|
30
|
-
- `workspaceRoot` — absolute path to the workspace (may be null)
|
|
30
|
+
- `workspaceRoot` — absolute path to the workspace (a workspace marker; may be null)
|
|
31
31
|
|
|
32
32
|
## Step 2: Load Playbooks
|
|
33
33
|
|
|
@@ -19,9 +19,10 @@ the bundle's own to track, only the member todos.
|
|
|
19
19
|
|
|
20
20
|
## Step 1: Load context
|
|
21
21
|
|
|
22
|
-
Read `.syntaur/context.json` from the current working
|
|
23
|
-
contain `bundleId` (a bundle context). If
|
|
24
|
-
|
|
22
|
+
Read `.syntaur/context.json` (a workspace marker) from the current working
|
|
23
|
+
directory. It must contain `bundleId` (a bundle context). If there is no
|
|
24
|
+
`bundleId` but the session has an open engagement (an active assignment), stop
|
|
25
|
+
and tell the user: "This session is bound to an assignment, not a bundle.
|
|
25
26
|
Use `/plan-assignment` instead, or `/grab-bundle <id>` to switch."
|
|
26
27
|
|
|
27
28
|
Extract `bundleId`, `bundleScope`, `bundleScopeId`, `todoIds`, `planDir`.
|
|
@@ -38,12 +38,15 @@ todos are never deleted.**
|
|
|
38
38
|
|
|
39
39
|
## Step 1: Verify there is an active assignment
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
`
|
|
43
|
-
`assignmentDir`.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
The active assignment is resolved from the session's open engagement. Run
|
|
42
|
+
`syntaur session resume --json` to read the bound `assignmentSlug`,
|
|
43
|
+
`projectSlug` (may be null for standalone), and `assignmentDir`.
|
|
44
|
+
`.syntaur/context.json` is only a workspace marker — do not read the assignment
|
|
45
|
+
from it.
|
|
46
|
+
|
|
47
|
+
If there is no open engagement (no active assignment), abort with: "No active
|
|
48
|
+
assignment for this session — grab one first." Run `grab-assignment` first. Do
|
|
49
|
+
not invent values.
|
|
47
50
|
|
|
48
51
|
## Step 2: Confirm the prior plan was implemented
|
|
49
52
|
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
name: resume-session
|
|
3
3
|
description: >-
|
|
4
4
|
Re-orient a fresh Syntaur session on the active assignment without
|
|
5
|
-
re-reading the full transcript.
|
|
6
|
-
|
|
5
|
+
re-reading the full transcript. Resolves the active assignment from the
|
|
6
|
+
session's open engagement and loads the latest saved session summary and any
|
|
7
|
+
open handoff. Use when the user says
|
|
7
8
|
"resume", "pick up where we left off", "continue this assignment", or after
|
|
8
9
|
a compact / new session start. Symmetric counterpart to
|
|
9
10
|
`/save-session-summary`.
|
|
@@ -28,15 +29,20 @@ freely; nothing on disk changes.
|
|
|
28
29
|
- Saving the current session's progress — that's `/save-session-summary` (the
|
|
29
30
|
symmetric write side).
|
|
30
31
|
|
|
31
|
-
## Step 1: Verify there is an active
|
|
32
|
+
## Step 1: Verify there is an active assignment
|
|
32
33
|
|
|
33
34
|
Run `syntaur session resume`. The CLI:
|
|
34
35
|
|
|
35
|
-
1.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
1. Resolves the active assignment from the session's OPEN engagement (the
|
|
37
|
+
assignment this session is currently bound to). `.syntaur/context.json` is
|
|
38
|
+
only a workspace marker — it identifies the repository/branch/worktree, not
|
|
39
|
+
the active assignment.
|
|
40
|
+
2. Aborts (exit 1) with a clear message when there is no open engagement —
|
|
41
|
+
"No active assignment for this session — grab one first" — telling the user
|
|
42
|
+
to run `grab-assignment`.
|
|
43
|
+
3. Otherwise resolves the assignment dir from the engagement and scans
|
|
44
|
+
`<assignmentDir>/sessions/<sid>/summary.md`, picking the most recently
|
|
45
|
+
modified.
|
|
40
46
|
4. Reads `<assignmentDir>/handoff.md` (the canonical single-file handoff per
|
|
41
47
|
assignment, managed by `complete-assignment`) and reports it if its body
|
|
42
48
|
has been written beyond the scaffolded placeholder.
|
|
@@ -26,11 +26,11 @@ mid-assignment continuity** — distinct from `handoff.md`, which is the
|
|
|
26
26
|
|
|
27
27
|
## Step 1: Load Context
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
|
|
30
30
|
|
|
31
|
-
If
|
|
31
|
+
If there is no open engagement (no active assignment), tell the user: "No active assignment for this session — grab one first." and stop. `.syntaur/context.json` is only a workspace marker; do not read the assignment from it.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
From the resolved engagement, note:
|
|
34
34
|
- `assignmentDir` (absolute path) — required.
|
|
35
35
|
|
|
36
36
|
**Do not read the session id from `context.json` for identity.** That scalar is
|
|
@@ -86,7 +86,7 @@ printf '%s' "$BODY" | syntaur session save
|
|
|
86
86
|
# Pass --session-id <id> only to override (e.g. you already have $CLAUDE_CODE_SESSION_ID).
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
Resolves the active assignment from
|
|
89
|
+
Resolves the active assignment from the session's open engagement (or pass
|
|
90
90
|
`--assignment <slug> [--project <slug>]`). `--session-id` now defaults to the
|
|
91
91
|
**resolved** session (env → process tree → transcript), falling back to the
|
|
92
92
|
`context.json` hint only as a last resort — so a co-tenant that clobbered the
|
|
@@ -35,11 +35,14 @@ implementation code until workspace fields are set.
|
|
|
35
35
|
|
|
36
36
|
## Step 1: Resolve the assignment file
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
`
|
|
38
|
+
The active assignment is resolved from the session's open engagement — `syntaur
|
|
39
|
+
workspace set` (Step 3) targets it automatically. `.syntaur/context.json` is
|
|
40
|
+
only a workspace marker; do not read the assignment from it.
|
|
40
41
|
|
|
41
|
-
If no
|
|
42
|
-
first."
|
|
42
|
+
If there is no open engagement (no active assignment), the CLI aborts with "No
|
|
43
|
+
active assignment for this session — grab one first." Run `grab-assignment`
|
|
44
|
+
first, or pass `--assignment <slug> [--project <slug>]` to target one
|
|
45
|
+
explicitly.
|
|
43
46
|
|
|
44
47
|
## Step 2: Gather inputs
|
|
45
48
|
|
|
@@ -68,8 +71,8 @@ syntaur workspace set \
|
|
|
68
71
|
--parent-branch <parent>
|
|
69
72
|
```
|
|
70
73
|
|
|
71
|
-
Targets the active assignment from
|
|
72
|
-
`--assignment <slug> [--project <slug>]` to target one explicitly. The command
|
|
74
|
+
Targets the active assignment from the session's open engagement by default;
|
|
75
|
+
pass `--assignment <slug> [--project <slug>]` to target one explicitly. The command
|
|
73
76
|
does the whole safe write in one atomic step:
|
|
74
77
|
|
|
75
78
|
- **Pre-write validation** — runs the same checks as `syntaur doctor
|