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.
Files changed (136) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dashboard/dist/assets/{_basePickBy-DKk6tHtk.js → _basePickBy-BfpzwNC3.js} +1 -1
  3. package/dashboard/dist/assets/{_baseUniq-DM-f7DWz.js → _baseUniq-wFEHBTCT.js} +1 -1
  4. package/dashboard/dist/assets/{arc-ZBlA3YdV.js → arc-Bdcw4sCg.js} +1 -1
  5. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-BUmvtGTF.js → architectureDiagram-2XIMDMQ5-BessFAtJ.js} +1 -1
  6. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-B3qxWK6s.js → blockDiagram-WCTKOSBZ-CmjyyZPp.js} +1 -1
  7. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BEq_UJO-.js → c4Diagram-IC4MRINW-dT6p8cwc.js} +1 -1
  8. package/dashboard/dist/assets/channel-BOguQ5S4.js +1 -0
  9. package/dashboard/dist/assets/{chunk-4BX2VUAB-C-Y9ryMm.js → chunk-4BX2VUAB-BlY-k8DY.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-55IACEB6-CGdtbsjw.js → chunk-55IACEB6-CtQ0p0jb.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-FMBD7UC4-DllxJhUp.js → chunk-FMBD7UC4-DEevt_Yh.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-JSJVCQXG-jjMM8O5F.js → chunk-JSJVCQXG-CpjLL7Nh.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-KX2RTZJC-B_6BPltQ.js → chunk-KX2RTZJC-BWNRms_o.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-NQ4KR5QH-D0hJiXHp.js → chunk-NQ4KR5QH-qo2zbylv.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-QZHKN3VN-BCWo4hLS.js → chunk-QZHKN3VN-DRvojtzc.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-WL4C6EOR-DH_jEAwg.js → chunk-WL4C6EOR-A40iPU5N.js} +1 -1
  17. package/dashboard/dist/assets/classDiagram-VBA2DB6C-BLSHooma.js +1 -0
  18. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BLSHooma.js +1 -0
  19. package/dashboard/dist/assets/clone-iSEXw5tA.js +1 -0
  20. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-5ld00TOH.js → cose-bilkent-S5V4N54A-CYaO7nsk.js} +1 -1
  21. package/dashboard/dist/assets/{dagre-KLK3FWXG-Cnu6eQWy.js → dagre-KLK3FWXG-NX3inwVZ.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-E7M64L7V-_CBBKNP-.js → diagram-E7M64L7V-D9cJwhQW.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-IFDJBPK2-DE6WjIb1.js → diagram-IFDJBPK2-Bo5sFrMg.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-P4PSJMXO-DpW7UzNK.js → diagram-P4PSJMXO-DfRH0XU7.js} +1 -1
  25. package/dashboard/dist/assets/{erDiagram-INFDFZHY-BD2409fE.js → erDiagram-INFDFZHY-BgP1bwgw.js} +1 -1
  26. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-1p0khhFI.js → flowDiagram-PKNHOUZH-C8Wws1ci.js} +1 -1
  27. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-B2zFyA4s.js → ganttDiagram-A5KZAMGK-BgJhUuj8.js} +1 -1
  28. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-bH-4YH7h.js → gitGraphDiagram-K3NZZRJ6-CI9FgCgo.js} +1 -1
  29. package/dashboard/dist/assets/{graph-BT24B6iQ.js → graph-B_7GyeiA.js} +1 -1
  30. package/dashboard/dist/assets/{index-Cxqr3rQB.js → index-CbndxFlO.js} +3 -3
  31. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-CMzP4Hcg.js → infoDiagram-LFFYTUFH-BEtZcRxI.js} +1 -1
  32. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-DMEmFC7M.js → ishikawaDiagram-PHBUUO56-0o9Bksuc.js} +1 -1
  33. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-CAtzYQUm.js → journeyDiagram-4ABVD52K-RyRU3as7.js} +1 -1
  34. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-d1JVbtvX.js → kanban-definition-K7BYSVSG-hLrHHizB.js} +1 -1
  35. package/dashboard/dist/assets/{layout-BVuI38I_.js → layout-w458wydd.js} +1 -1
  36. package/dashboard/dist/assets/{linear-Bc8PGMbp.js → linear-CnRlR5_w.js} +1 -1
  37. package/dashboard/dist/assets/{mermaid.core-UtwFYLNj.js → mermaid.core-DJ_9ty0Y.js} +4 -4
  38. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-DHc5RCDj.js → mindmap-definition-YRQLILUH-C7TIzJVC.js} +1 -1
  39. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-9anIsdIA.js → pieDiagram-SKSYHLDU-BZ9ysteM.js} +1 -1
  40. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-FZ0D9HnU.js → quadrantDiagram-337W2JSQ-DpaMVSO1.js} +1 -1
  41. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-BkjCvH_u.js → requirementDiagram-Z7DCOOCP-EXFcskZZ.js} +1 -1
  42. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DzqwYHDo.js → sankeyDiagram-WA2Y5GQK-BdImdXkY.js} +1 -1
  43. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-BW4g5Ao-.js → sequenceDiagram-2WXFIKYE-CWN3faYf.js} +1 -1
  44. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-D0tKU3Z0.js → stateDiagram-RAJIS63D-DIQdn-BF.js} +1 -1
  45. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-1u62oWzq.js +1 -0
  46. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-Bu269QDX.js → timeline-definition-YZTLITO2-DMTIpUOE.js} +1 -1
  47. package/dashboard/dist/assets/{treemap-KZPCXAKY-BGu_rrva.js → treemap-KZPCXAKY-Y2AH2GB7.js} +1 -1
  48. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-Cx_n5FRZ.js → vennDiagram-LZ73GAT5-BF4bJK-l.js} +1 -1
  49. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-BOJsKV_W.js → xychartDiagram-JWTSCODW-DH-tOBC5.js} +1 -1
  50. package/dashboard/dist/index.html +1 -1
  51. package/dist/dashboard/server.js +1427 -550
  52. package/dist/dashboard/server.js.map +1 -1
  53. package/dist/index.js +2816 -1559
  54. package/dist/index.js.map +1 -1
  55. package/dist/launch/index.js +913 -141
  56. package/dist/launch/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
  59. package/platforms/claude-code/hooks/enforce-boundaries.sh +49 -16
  60. package/platforms/claude-code/hooks/session-cleanup.sh +4 -2
  61. package/platforms/claude-code/skills/add-memory/SKILL.md +3 -2
  62. package/platforms/claude-code/skills/add-resource/SKILL.md +3 -2
  63. package/platforms/claude-code/skills/bundle-worktree/SKILL.md +3 -3
  64. package/platforms/claude-code/skills/capture-artifacts/SKILL.md +2 -2
  65. package/platforms/claude-code/skills/claim-resource/SKILL.md +3 -3
  66. package/platforms/claude-code/skills/clear-assignment/SKILL.md +9 -27
  67. package/platforms/claude-code/skills/complete-assignment/SKILL.md +3 -3
  68. package/platforms/claude-code/skills/create-assignment/SKILL.md +2 -2
  69. package/platforms/claude-code/skills/extend-resource/SKILL.md +2 -2
  70. package/platforms/claude-code/skills/grab-assignment/SKILL.md +17 -12
  71. package/platforms/claude-code/skills/grab-bundle/SKILL.md +10 -6
  72. package/platforms/claude-code/skills/log-progress/SKILL.md +6 -4
  73. package/platforms/claude-code/skills/plan-assignment/SKILL.md +3 -3
  74. package/platforms/claude-code/skills/plan-bundle/SKILL.md +4 -3
  75. package/platforms/claude-code/skills/replan/SKILL.md +9 -6
  76. package/platforms/claude-code/skills/resume-session/SKILL.md +14 -8
  77. package/platforms/claude-code/skills/save-session-summary/SKILL.md +4 -4
  78. package/platforms/claude-code/skills/set-workspace/SKILL.md +9 -6
  79. package/platforms/claude-code/skills/syntaur-protocol/SKILL.md +9 -7
  80. package/platforms/claude-code/skills/syntaur-protocol/references/file-ownership.md +1 -1
  81. package/platforms/claude-code/skills/syntaur-worktree/SKILL.md +11 -7
  82. package/platforms/codex/.codex-plugin/plugin.json +1 -1
  83. package/platforms/codex/scripts/enforce-boundaries.sh +74 -12
  84. package/platforms/codex/scripts/session-cleanup.sh +20 -13
  85. package/platforms/codex/skills/add-memory/SKILL.md +3 -2
  86. package/platforms/codex/skills/add-resource/SKILL.md +3 -2
  87. package/platforms/codex/skills/bundle-worktree/SKILL.md +3 -3
  88. package/platforms/codex/skills/capture-artifacts/SKILL.md +2 -2
  89. package/platforms/codex/skills/claim-resource/SKILL.md +3 -3
  90. package/platforms/codex/skills/clear-assignment/SKILL.md +9 -27
  91. package/platforms/codex/skills/complete-assignment/SKILL.md +3 -3
  92. package/platforms/codex/skills/create-assignment/SKILL.md +2 -2
  93. package/platforms/codex/skills/extend-resource/SKILL.md +2 -2
  94. package/platforms/codex/skills/grab-assignment/SKILL.md +17 -12
  95. package/platforms/codex/skills/grab-bundle/SKILL.md +10 -6
  96. package/platforms/codex/skills/log-progress/SKILL.md +6 -4
  97. package/platforms/codex/skills/plan-assignment/SKILL.md +3 -3
  98. package/platforms/codex/skills/plan-bundle/SKILL.md +4 -3
  99. package/platforms/codex/skills/replan/SKILL.md +9 -6
  100. package/platforms/codex/skills/resume-session/SKILL.md +14 -8
  101. package/platforms/codex/skills/save-session-summary/SKILL.md +4 -4
  102. package/platforms/codex/skills/set-workspace/SKILL.md +9 -6
  103. package/platforms/codex/skills/syntaur-protocol/SKILL.md +9 -7
  104. package/platforms/codex/skills/syntaur-protocol/references/file-ownership.md +1 -1
  105. package/platforms/codex/skills/syntaur-worktree/SKILL.md +11 -7
  106. package/platforms/hermes/plugins/syntaur/__init__.py +29 -3
  107. package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
  108. package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
  109. package/platforms/hermes/plugins/syntaur/boundary.py +18 -9
  110. package/platforms/pi/extensions/syntaur/index.ts +84 -29
  111. package/skills/add-memory/SKILL.md +3 -2
  112. package/skills/add-resource/SKILL.md +3 -2
  113. package/skills/bundle-worktree/SKILL.md +3 -3
  114. package/skills/capture-artifacts/SKILL.md +2 -2
  115. package/skills/claim-resource/SKILL.md +3 -3
  116. package/skills/clear-assignment/SKILL.md +9 -27
  117. package/skills/complete-assignment/SKILL.md +3 -3
  118. package/skills/create-assignment/SKILL.md +2 -2
  119. package/skills/extend-resource/SKILL.md +2 -2
  120. package/skills/grab-assignment/SKILL.md +17 -12
  121. package/skills/grab-bundle/SKILL.md +10 -6
  122. package/skills/log-progress/SKILL.md +6 -4
  123. package/skills/plan-assignment/SKILL.md +3 -3
  124. package/skills/plan-bundle/SKILL.md +4 -3
  125. package/skills/replan/SKILL.md +9 -6
  126. package/skills/resume-session/SKILL.md +14 -8
  127. package/skills/save-session-summary/SKILL.md +4 -4
  128. package/skills/set-workspace/SKILL.md +9 -6
  129. package/skills/syntaur-protocol/SKILL.md +9 -7
  130. package/skills/syntaur-protocol/references/file-ownership.md +1 -1
  131. package/skills/syntaur-worktree/SKILL.md +11 -7
  132. package/dashboard/dist/assets/channel-fypxffzQ.js +0 -1
  133. package/dashboard/dist/assets/classDiagram-VBA2DB6C-1KnjQvtL.js +0 -1
  134. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-1KnjQvtL.js +0 -1
  135. package/dashboard/dist/assets/clone-CKMabBhS.js +0 -1
  136. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DxWQhjNO.js +0 -1
@@ -14,7 +14,7 @@ metadata:
14
14
 
15
15
  # Clear Assignment
16
16
 
17
- Drop the active assignment binding from the current workspace. The assignment itself is left untouched in `~/.syntaur/projects/.../assignments/` — only the local `.syntaur/context.json` pointer is cleared so the session is no longer scoped to it.
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
- - `--keep-session` — preserve `sessionId` / `transcriptPath` fields in `context.json` (just strip the assignment fields). Default: full delete.
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
- Read `.syntaur/context.json` from the current working directory.
35
+ The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
37
36
 
38
- - If the file does not exist, tell the user: "No active assignment context to clear." and stop.
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
- Otherwise extract: `projectSlug`, `assignmentSlug`, `assignmentDir`, `title`.
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: Clear the Context File
69
+ ## Step 4: Close the Engagement
72
70
 
73
- Default behaviordelete the file entirely:
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
- ```bash
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` you captured from the original `context.json` in Step 1 (before deletion) — that scalar is a shared, legacy hint a co-tenant can clobber, so don't treat it as authoritative:
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
- Read `.syntaur/context.json` from the current working directory.
22
+ The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
23
23
 
24
- If the file does not exist, tell the user: "No active assignment found. Run `grab-assignment` first."
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
- Extract: `projectSlug`, `assignmentSlug`, `assignmentDir`, `projectDir`.
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 `.syntaur/context.json` for an active assignment. If present, default `--project` to that context's `projectSlug` and confirm with the user: "Add this assignment to project `<projectSlug>`?"
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 active context and no project flag, ask the user which project to add it to, or whether it should be a one-off.
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 assignment context
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 has neither `sessionId` nor any of `projectSlug`/`assignmentSlug`/`assignmentDir`, abort with:
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
- Check if `.syntaur/context.json` already exists in the current working directory.
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
- - If it exists AND contains BOTH `projectSlug` and `assignmentSlug`, it represents an active assignment. Warn the user: "You already have an active assignment: `<assignmentSlug>` in project `<projectSlug>`. Grabbing a new one will replace this context. Proceed?" — stop if the user says no.
29
- - If it exists but only has session fields (`sessionId`, `transcriptPath`) and no project/assignment, it was populated by the platform's SessionStart hook (Claude Code, etc.) and does NOT represent an active assignment. Proceed silently and merge assignment fields on top in Step 5.
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 Context File
84
+ ## Step 5: Create or Merge the Workspace Marker
79
85
 
80
- Merge assignment context into `.syntaur/context.json`. Never overwriteif the file already exists (e.g., platform SessionStart hook populated `sessionId` / `transcriptPath`), preserve those fields.
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 assignment payload:
94
+ Prepare the workspace-marker payload:
87
95
 
88
96
  ```json
89
97
  {
90
- "projectSlug": "<project-slug or null for standalone>",
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
- Read `.syntaur/context.json` in the current working directory.
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
- - If it has only `sessionId` (platform SessionStart hook seeded it), proceed
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
- Read `.syntaur/context.json` from the current working directory. Extract
43
- `assignmentDir`. If missing, abort with: "No active assignment. Run
44
- `grab-assignment` first."
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 `.syntaur/context.json`
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
- Read `.syntaur/context.json` from the current working directory. If the file does not exist, tell the user: "No active assignment found. Run `grab-assignment` first to claim an assignment."
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
- Extract:
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 directory. It must
23
- contain `bundleId` (a bundle context). If it instead has assignment fields,
24
- stop and tell the user: "Active context is an assignment, not a bundle.
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
- Read `.syntaur/context.json` from the current working directory. Extract
42
- `assignmentSlug`, `projectSlug` (may be null for standalone), and
43
- `assignmentDir`.
44
-
45
- If the file is missing or has no `assignmentSlug`, abort with: "No active
46
- Syntaur assignment. Run `grab-assignment` first." Do not invent values.
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. Loads the latest saved session summary,
6
- `.syntaur/context.json`, and any open handoff. Use when the user says
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 context
32
+ ## Step 1: Verify there is an active assignment
32
33
 
33
34
  Run `syntaur session resume`. The CLI:
34
35
 
35
- 1. Reads `.syntaur/context.json` from the current working directory.
36
- 2. Aborts (exit 1) with a clear message if missing or if no `assignmentDir`
37
- is set telling the user to run `grab-assignment` first.
38
- 3. Otherwise scans `<assignmentDir>/sessions/<sid>/summary.md` and picks the
39
- most recently modified.
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
- Read `.syntaur/context.json` from the current working directory.
29
+ The active assignment is resolved from the session's open engagement. Run `syntaur session resume --json` to read it.
30
30
 
31
- If the file does not exist, tell the user: "No active assignment found. Run `grab-assignment` first." and stop.
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
- Extract:
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 `.syntaur/context.json` (or pass
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
- Read `.syntaur/context.json` from the current working directory. Extract
39
- `assignmentDir`. The target file is `<assignmentDir>/assignment.md`.
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 context, abort with: "No active assignment. Run `grab-assignment`
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 `.syntaur/context.json` by default; pass
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
@@ -32,7 +32,7 @@ Respect file ownership boundaries. The Claude Code and Codex plugins enforce the
32
32
  - `~/.syntaur/projects/<project>/resources/<slug>.md`
33
33
  - `~/.syntaur/projects/<project>/memories/<slug>.md`
34
34
  3. **Workspace files** inside the assignment's configured `workspace.worktreePath` / `workspace.repository`.
35
- 4. **Context file:** `.syntaur/context.json` in the current working directory.
35
+ 4. **Workspace marker:** `.syntaur/context.json` in the current working directory (repository/branch/worktree markers plus legacy session/lease bookkeeping — not the active-assignment source of truth).
36
36
 
37
37
  ### Files written only via CLI (never edit directly)
38
38
 
@@ -51,16 +51,18 @@ Per-project `agent.md` / `claude.md` do NOT exist in protocol v2.0. Agent-level
51
51
 
52
52
  ## Current Assignment Context
53
53
 
54
- If `.syntaur/context.json` exists in the current working directory, read it before making changes. Fields you will see:
54
+ The **active assignment** is resolved from the session's OPEN engagement — the assignment this session is currently bound to (established by `syntaur track-session`). It is NOT read from `.syntaur/context.json`. To learn the active assignment, run `syntaur session resume` (or `--json`); to bind a different one, `grab-assignment` (which calls `track-session`).
55
55
 
56
- - `projectSlug` containing project slug (`null` for standalone assignments)
57
- - `assignmentSlug` — assignment slug (for standalone, the UUID is the folder name; slug is display-only)
58
- - `projectDir` — absolute path to the project folder (`null` for standalone)
59
- - `assignmentDir` — absolute path to the assignment folder
56
+ `.syntaur/context.json` is a WORKSPACE MARKER file — it identifies the workspace directory and carries legacy session and resource-lease bookkeeping. It is NOT authoritative for the active assignment. Read it for workspace markers and leases; do NOT treat `projectSlug` / `assignmentSlug` / `assignmentDir` as the active-assignment source of truth (any such scalars are non-authoritative legacy hints). Fields you may see:
57
+
58
+ - `repository` — workspace repository (path or remote URL)
59
+ - `branch` — workspace branch, if known
60
+ - `worktreePath` — absolute path to the worktree, if this workspace is a worktree
60
61
  - `workspaceRoot` — absolute path to the code workspace
61
- - `sessionId` — real agent-runtime session id (never a synthesized UUID)
62
+ - `sessionId` — real agent-runtime session id (legacy hint; never a synthesized UUID, and a co-tenant can clobber it — not authoritative for identity)
62
63
  - `transcriptPath` — absolute path to the agent's rollout/transcript file, if known
63
64
  - `leases` — array of active resource-lease records (managed by `/claim-resource` and `/release-resource`). Entry shape: `{ lease_id, inventory_slug, member_id, expires_at, metadata, claimed_at }`. Leases are NOT auto-released on session end or assignment completion in v1 — call `/release-resource` explicitly (or let the TTL expire).
65
+ - `bundleId` and related bundle fields — present when this workspace is bound to a todo bundle (managed by the bundle skills).
64
66
 
65
67
  ## Required Reading Order
66
68
 
@@ -64,4 +64,4 @@ When working on code (not protocol files), you may write to files within the wor
64
64
 
65
65
  - `workspace.worktreePath` or `workspace.repository` defines your code root.
66
66
  - You may create and edit source files within that workspace.
67
- - The `.syntaur/context.json` context file in your working directory is also writable (merge, don't overwrite — the platform SessionStart hook may have populated `sessionId` and `transcriptPath`).
67
+ - The `.syntaur/context.json` workspace-marker file in your working directory is also writable (merge, don't overwrite — the platform SessionStart hook may have populated `sessionId` and `transcriptPath`). It marks the workspace (repository/branch/worktree); it is not the active-assignment source of truth — the active assignment resolves from the session's open engagement.
@@ -23,8 +23,9 @@ operations:
23
23
  transactionally — rolls back the worktree on write failure).
24
24
  3. `syntaur assign` + `syntaur start` — claim the assignment for this agent
25
25
  and transition to `in_progress`.
26
- 4. Write `.syntaur/context.json` inside the new worktree so the session is
27
- bound there.
26
+ 4. Write `.syntaur/context.json` (a workspace marker) inside the new worktree,
27
+ then `syntaur track-session` to bind the session's engagement to the
28
+ assignment.
28
29
 
29
30
  ## When NOT to use this skill
30
31
 
@@ -82,12 +83,15 @@ syntaur start <assignment> --project <project-slug> # only if status was pendi
82
83
  Skip `start` for any non-`pending` status — never rewind a `review`,
83
84
  `completed`, or `failed` assignment.
84
85
 
85
- ## Step 5: Bind the new worktree to your session
86
+ ## Step 5: Write the workspace marker
86
87
 
87
- `cd` into the new worktree path. Write
88
- `<worktreePath>/.syntaur/context.json` mirroring the format produced by
89
- `/grab-assignment` (projectSlug, assignmentSlug, projectDir, assignmentDir,
90
- workspaceRoot, title, branch, sessionId, transcriptPath, grabbedAt).
88
+ `cd` into the new worktree path. Write `<worktreePath>/.syntaur/context.json`
89
+ mirroring the WORKSPACE-MARKER format produced by `/grab-assignment`:
90
+ `repository`, `branch`, `worktreePath`, `workspaceRoot`, `grabbedAt`, plus
91
+ `sessionId` / `transcriptPath` when known. Do NOT write `projectSlug` /
92
+ `assignmentSlug` / `assignmentDir` / `projectDir` / `title` — context.json is a
93
+ workspace marker, not the active-assignment source. The assignment binds in the
94
+ next step via the session's engagement (`track-session`).
91
95
 
92
96
  If the runtime exposes a real session id (e.g. Claude Code's
93
97
  `~/.claude/sessions/`), include it. Otherwise omit `sessionId` entirely; the
@@ -1 +0,0 @@
1
- import{ap as o,aq as n}from"./mermaid.core-UtwFYLNj.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-WL4C6EOR-DH_jEAwg.js";import{_ as i}from"./mermaid.core-UtwFYLNj.js";import"./index-Cxqr3rQB.js";import"./chunk-FMBD7UC4-DllxJhUp.js";import"./chunk-JSJVCQXG-jjMM8O5F.js";import"./chunk-55IACEB6-CGdtbsjw.js";import"./chunk-KX2RTZJC-B_6BPltQ.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-WL4C6EOR-DH_jEAwg.js";import{_ as i}from"./mermaid.core-UtwFYLNj.js";import"./index-Cxqr3rQB.js";import"./chunk-FMBD7UC4-DllxJhUp.js";import"./chunk-JSJVCQXG-jjMM8O5F.js";import"./chunk-55IACEB6-CGdtbsjw.js";import"./chunk-KX2RTZJC-B_6BPltQ.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{b as r}from"./_baseUniq-DM-f7DWz.js";var e=4;function a(o){return r(o,e)}export{a as c};
@@ -1 +0,0 @@
1
- import{s as e,b as r,a,S as s}from"./chunk-NQ4KR5QH-D0hJiXHp.js";import{_ as i}from"./mermaid.core-UtwFYLNj.js";import"./index-Cxqr3rQB.js";import"./chunk-55IACEB6-CGdtbsjw.js";import"./chunk-KX2RTZJC-B_6BPltQ.js";var p={parser:a,get db(){return new s(2)},renderer:r,styles:e,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{p as diagram};