@workit-dev/core 0.0.1 → 1.0.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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -43
  3. package/package.json +56 -6
  4. package/schemas/config.json +74 -0
  5. package/schemas/vcs.json +79 -0
  6. package/schemas/workspaces.json +1029 -0
  7. package/schemas/youtrack.json +84 -0
  8. package/scripts/analyze-release-scope.ts +215 -0
  9. package/scripts/bundled-deps.json +131 -0
  10. package/scripts/fixtures/sample-plan.md +15 -0
  11. package/scripts/fixtures/sample-sdd/progress.md +2 -0
  12. package/scripts/install-codex-plugin.sh +28 -0
  13. package/scripts/install-cursor-plugin.sh +146 -0
  14. package/scripts/install-opencode-plugin.sh +79 -0
  15. package/scripts/install-pi-package.sh +56 -0
  16. package/scripts/lib/config-dir.sh +28 -0
  17. package/scripts/publish-changed-packages.ts +395 -0
  18. package/scripts/rewrite-workspace-deps.ts +53 -0
  19. package/scripts/run-cursor-mcp.sh +6 -0
  20. package/scripts/sync-release-manifests.ts +82 -0
  21. package/scripts/sync-runtime.sh +142 -0
  22. package/scripts/validate-cursor-marketplace.ts +171 -0
  23. package/scripts/verify-bundle-sources.ts +134 -0
  24. package/scripts/write-schemas.ts +16 -0
  25. package/skills/workit-architecture/SKILL.md +72 -0
  26. package/skills/workit-architecture/agents/openai.yaml +3 -0
  27. package/skills/workit-architecture/references/instruction-files.md +52 -0
  28. package/skills/workit-architecture/references/vocabulary.md +53 -0
  29. package/skills/workit-bdd/SKILL.md +53 -0
  30. package/skills/workit-continue/SKILL.md +54 -0
  31. package/skills/workit-debug/SKILL.md +45 -0
  32. package/skills/workit-deslop/SKILL.md +58 -0
  33. package/skills/workit-fanout/SKILL.md +71 -0
  34. package/skills/workit-fanout/references/brief.md +141 -0
  35. package/skills/workit-fanout/references/orchestration.md +169 -0
  36. package/skills/workit-implement/SKILL.md +71 -0
  37. package/skills/workit-retro/SKILL.md +72 -0
  38. package/skills/workit-retro/agents/openai.yaml +3 -0
  39. package/skills/workit-retro/references/sources.md +35 -0
  40. package/skills/workit-retro/references/steering.md +39 -0
  41. package/skills/workit-review/SKILL.md +66 -0
  42. package/skills/workit-review/references/impact.md +24 -0
  43. package/skills/workit-shape/SKILL.md +71 -0
  44. package/skills/workit-shape/references/diagrams.md +17 -0
  45. package/skills/workit-shape/references/knowledge.md +61 -0
  46. package/skills/workit-shape/references/mockups.md +15 -0
  47. package/skills/workit-shape/references/slicing.md +44 -0
  48. package/skills/workit-ship/SKILL.md +71 -0
  49. package/skills/workit-ship/references/changelog.md +44 -0
  50. package/skills/workit-ship/references/pr-body.md +32 -0
  51. package/skills/workit-ship/references/release.md +39 -0
  52. package/skills/workit-test-audit/SKILL.md +54 -0
  53. package/skills/workit-verify-app/SKILL.md +68 -0
  54. package/skills/workit-verify-app/references/template.md +51 -0
  55. package/src/autonomy.ts +910 -0
  56. package/src/check-config.ts +613 -0
  57. package/src/checks.ts +534 -0
  58. package/src/ci-waiter.ts +159 -0
  59. package/src/core/boundary.ts +55 -0
  60. package/src/core/branch-policy.ts +112 -0
  61. package/src/core/branch.ts +1192 -0
  62. package/src/core/changelog-gate.ts +349 -0
  63. package/src/core/changelog-merge.ts +214 -0
  64. package/src/core/changelog.ts +392 -0
  65. package/src/core/cleanup.ts +638 -0
  66. package/src/core/cli-locate.ts +173 -0
  67. package/src/core/commit-flavors.ts +65 -0
  68. package/src/core/config-schemas.ts +653 -0
  69. package/src/core/config.ts +351 -0
  70. package/src/core/context-read.ts +144 -0
  71. package/src/core/docs-gate.ts +69 -0
  72. package/src/core/finding-evidence.ts +89 -0
  73. package/src/core/finding-queue.ts +36 -0
  74. package/src/core/git.ts +73 -0
  75. package/src/core/gitignore.ts +52 -0
  76. package/src/core/heavy-eta.ts +170 -0
  77. package/src/core/heavy-lease.ts +290 -0
  78. package/src/core/heavy-rules.ts +373 -0
  79. package/src/core/heavy-scope.ts +131 -0
  80. package/src/core/heavy-words.ts +83 -0
  81. package/src/core/heavy.ts +535 -0
  82. package/src/core/hygiene.ts +149 -0
  83. package/src/core/init.ts +218 -0
  84. package/src/core/live-session.ts +333 -0
  85. package/src/core/logger.ts +310 -0
  86. package/src/core/methods.ts +185 -0
  87. package/src/core/model-fallback.ts +208 -0
  88. package/src/core/node-resolve.mjs +249 -0
  89. package/src/core/operation-input.ts +632 -0
  90. package/src/core/package-root.ts +28 -0
  91. package/src/core/policy/attributes.ts +97 -0
  92. package/src/core/policy/bookkeeping.ts +119 -0
  93. package/src/core/policy/carry.ts +122 -0
  94. package/src/core/policy/check-evidence.ts +115 -0
  95. package/src/core/policy/current-judgment.ts +20 -0
  96. package/src/core/policy/derive.ts +387 -0
  97. package/src/core/policy/judgment.ts +246 -0
  98. package/src/core/policy/lane.ts +562 -0
  99. package/src/core/policy/pr-lane.ts +32 -0
  100. package/src/core/policy/substance.ts +365 -0
  101. package/src/core/policy-resolver.ts +94 -0
  102. package/src/core/pr-create.ts +448 -0
  103. package/src/core/pr-template.ts +162 -0
  104. package/src/core/release-notes.ts +197 -0
  105. package/src/core/release-tracks.ts +779 -0
  106. package/src/core/remotes.ts +436 -0
  107. package/src/core/repo-context.ts +542 -0
  108. package/src/core/repo-paths.ts +29 -0
  109. package/src/core/resources.ts +1299 -0
  110. package/src/core/role-models.ts +603 -0
  111. package/src/core/route-intent.ts +305 -0
  112. package/src/core/rules.ts +65 -0
  113. package/src/core/runtime-identity.ts +63 -0
  114. package/src/core/safe-write.ts +87 -0
  115. package/src/core/scope-glob.ts +56 -0
  116. package/src/core/scripts.ts +6 -0
  117. package/src/core/skill-manifests.ts +173 -0
  118. package/src/core/store-lock.ts +374 -0
  119. package/src/core/support-matrix.ts +24 -0
  120. package/src/core/task-context.ts +247 -0
  121. package/src/core/task-contract.ts +1279 -0
  122. package/src/core/task-delivery.ts +109 -0
  123. package/src/core/task-engine.ts +2248 -0
  124. package/src/core/task-evaluation.ts +1147 -0
  125. package/src/core/task-store.ts +2649 -0
  126. package/src/core/task-view.ts +180 -0
  127. package/src/core/templates.ts +22 -0
  128. package/src/core/tracker-issues.ts +174 -0
  129. package/src/core/vcs-config.ts +540 -0
  130. package/src/core/workers.ts +62 -0
  131. package/src/core/workit-paths.mjs +242 -0
  132. package/src/core/workspace-branch-policy.ts +123 -0
  133. package/src/core/workspaces.ts +1745 -0
  134. package/src/core/youtrack-backend.ts +288 -0
  135. package/src/core/youtrack-tools.ts +260 -0
  136. package/src/core/youtrack-writes.ts +73 -0
  137. package/src/core/youtrack-ytrack.ts +217 -0
  138. package/src/core/youtrack.ts +454 -0
  139. package/src/core/ytrack-skill.ts +297 -0
  140. package/src/core.ts +171 -0
  141. package/src/deslop/lex.ts +271 -0
  142. package/src/deslop/scan.ts +232 -0
  143. package/src/duration.ts +27 -0
  144. package/src/fanout-brief.ts +486 -0
  145. package/src/fanout-check.ts +455 -0
  146. package/src/fanout-landed.ts +370 -0
  147. package/src/fanout-stack.ts +108 -0
  148. package/src/fanout-status.ts +362 -0
  149. package/src/fanout-worktree.ts +893 -0
  150. package/src/fanout.ts +1473 -0
  151. package/src/forge/exec.ts +385 -0
  152. package/src/forge/github.ts +831 -0
  153. package/src/forge/gitlab.ts +906 -0
  154. package/src/forge/issue-forge.ts +209 -0
  155. package/src/forge/issue-link.ts +468 -0
  156. package/src/forge/issue-ops.ts +314 -0
  157. package/src/forge/merge-gate-base-red.ts +72 -0
  158. package/src/forge/pr-body.ts +100 -0
  159. package/src/forge/pr-edit.ts +292 -0
  160. package/src/forge/pr-ops.ts +1109 -0
  161. package/src/forge/pr-status.ts +10 -0
  162. package/src/forge/redact.ts +195 -0
  163. package/src/forge/report.ts +994 -0
  164. package/src/forge/reruns.ts +132 -0
  165. package/src/forge/resolve.ts +509 -0
  166. package/src/forge/types.ts +242 -0
  167. package/src/forge/verify.ts +398 -0
  168. package/src/git/default-base.ts +130 -0
  169. package/src/git/env-redirect.ts +28 -0
  170. package/src/git/facts.ts +122 -0
  171. package/src/git/ops.ts +1823 -0
  172. package/src/git/refs-read.ts +332 -0
  173. package/src/git/release.ts +1020 -0
  174. package/src/git/rev.ts +1175 -0
  175. package/src/git/session-hook.ts +597 -0
  176. package/src/git/stage.ts +63 -0
  177. package/src/hooks/agent-model.ts +149 -0
  178. package/src/hooks/budget-signal.ts +284 -0
  179. package/src/hooks/context.ts +461 -0
  180. package/src/hooks/cwd-normalize.ts +79 -0
  181. package/src/hooks/deadline.ts +228 -0
  182. package/src/hooks/delivery-verbs.ts +182 -0
  183. package/src/hooks/descriptor.ts +124 -0
  184. package/src/hooks/handle.ts +433 -0
  185. package/src/hooks/heavy-gate.ts +99 -0
  186. package/src/hooks/hook-runs.ts +130 -0
  187. package/src/hooks/hosts/claude-code.ts +380 -0
  188. package/src/hooks/hosts/codex.ts +372 -0
  189. package/src/hooks/hosts/cursor.ts +419 -0
  190. package/src/hooks/hosts/fields.ts +98 -0
  191. package/src/hooks/hosts/opencode.ts +79 -0
  192. package/src/hooks/hosts/pi.ts +78 -0
  193. package/src/hooks/index.ts +60 -0
  194. package/src/hooks/model-limit.ts +378 -0
  195. package/src/hooks/model-switch.ts +35 -0
  196. package/src/hooks/policy.ts +29 -0
  197. package/src/hooks/process.ts +48 -0
  198. package/src/hooks/protocol.ts +135 -0
  199. package/src/hooks/raw-git.ts +2289 -0
  200. package/src/hooks/repeat-failure.ts +115 -0
  201. package/src/hooks/run.ts +54 -0
  202. package/src/hooks/session-marker.ts +151 -0
  203. package/src/hooks/shell-words.ts +532 -0
  204. package/src/hooks/skill-nudge.ts +295 -0
  205. package/src/hooks/spawn-gate.ts +72 -0
  206. package/src/hooks/standing-signal.ts +99 -0
  207. package/src/hooks/standing.ts +225 -0
  208. package/src/hooks/steering.ts +74 -0
  209. package/src/hooks/stop.ts +408 -0
  210. package/src/hooks/worktree-confine.ts +415 -0
  211. package/src/hooks/write-gate.ts +1174 -0
  212. package/src/host-session.ts +459 -0
  213. package/src/knowledge.ts +368 -0
  214. package/src/ledger.ts +2913 -0
  215. package/src/stack.ts +2570 -0
  216. package/src/store/event-log.ts +217 -0
  217. package/src/store/notes.ts +29 -0
  218. package/src/store/patch.ts +135 -0
  219. package/src/store/paths.ts +368 -0
  220. package/src/store/reduce.ts +203 -0
  221. package/src/test-audit-mocks.ts +309 -0
  222. package/src/verdict-cover.ts +151 -0
  223. package/src/worktree-deps.ts +142 -0
  224. package/templates/headers.md +3 -0
  225. package/templates/hygiene/.editorconfig +8 -0
  226. package/templates/hygiene/.gitattributes +3 -0
  227. package/templates/hygiene/CHANGELOG.md +14 -0
  228. package/templates/hygiene/CONTRIBUTING.md +3 -0
  229. package/templates/hygiene/LICENSE +21 -0
  230. package/templates/hygiene/README.md +3 -0
  231. package/templates/issue-update.md +5 -0
  232. package/templates/plan-template.md +26 -0
  233. package/templates/spec-template.md +64 -0
  234. package/templates/workit-contract.md +13 -0
@@ -0,0 +1,1029 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://unpkg.com/@workit-dev/core/schemas/workspaces.json",
4
+ "title": "Workit workspaces (workspaces.json in the Workit config dir)",
5
+ "type": "object",
6
+ "properties": {
7
+ "$schema": {
8
+ "type": "string",
9
+ "description": "The JSON Schema this file follows; Workit writes it and keeps your value."
10
+ },
11
+ "workspaces": {
12
+ "description": "Workspace entries, each mapping a path glob to its forge, policies and grants.",
13
+ "type": "array",
14
+ "items": {
15
+ "type": "object",
16
+ "properties": {
17
+ "name": {
18
+ "type": "string",
19
+ "description": "The workspace's unique name.",
20
+ "pattern": "\\S"
21
+ },
22
+ "glob": {
23
+ "type": "string",
24
+ "description": "The directories this entry covers, an absolute path glob with * and ** (`/home/you/work/**`); the narrowest match wins.",
25
+ "pattern": "\\S"
26
+ },
27
+ "vcs": {
28
+ "description": "The forge this workspace's repositories live on.",
29
+ "type": "object",
30
+ "properties": {
31
+ "provider": {
32
+ "type": "string",
33
+ "enum": ["gitlab", "github"],
34
+ "description": "The forge: github or gitlab."
35
+ },
36
+ "defaultTargetBranch": {
37
+ "description": "The branch PRs target by default.",
38
+ "type": "string",
39
+ "pattern": "\\S"
40
+ },
41
+ "tokenFile": {
42
+ "description": "A file holding the forge token for this workspace.",
43
+ "type": "string",
44
+ "pattern": "\\S"
45
+ },
46
+ "account": {
47
+ "description": "The forge login delivery runs as; grants need it to reach the forge.",
48
+ "type": "string",
49
+ "pattern": "\\S"
50
+ },
51
+ "host": {
52
+ "type": "string",
53
+ "pattern": "\\S",
54
+ "description": "A self-hosted forge's host name."
55
+ }
56
+ },
57
+ "required": ["provider"],
58
+ "additionalProperties": false
59
+ },
60
+ "autoApprove": {
61
+ "description": "Legacy (≤4.x) standing approvals, read once as autonomy grants; use `autonomy`.",
62
+ "anyOf": [
63
+ {
64
+ "type": "boolean"
65
+ },
66
+ {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "string",
70
+ "pattern": "\\S"
71
+ }
72
+ }
73
+ ]
74
+ },
75
+ "defaultEndpoint": {
76
+ "type": "string",
77
+ "enum": ["commit", "pr", "green", "merged"],
78
+ "description": "Where an unnamed request stops: commit (default), pr, green or merged. Set with `workit grant set`, like grants."
79
+ },
80
+ "verification": {
81
+ "description": "How a normal-risk behavior change is verified: proportional (default), self or independent. Set with `workit grant set`, like grants.",
82
+ "type": "string",
83
+ "enum": ["proportional", "self", "independent"]
84
+ },
85
+ "delegation": {
86
+ "type": "string",
87
+ "enum": ["inline-first", "lead-orchestrates"],
88
+ "description": "Who does the work: `inline-first` (default) keeps the lead working itself and refuses a slice without a reason to delegate; `lead-orchestrates` allows slices without one."
89
+ },
90
+ "changelog": {
91
+ "type": "string",
92
+ "enum": ["off", "update", "create"],
93
+ "description": "The Keep a Changelog step before a PR opens: `off` (default), `update` (an existing CHANGELOG.md needs an Unreleased entry from a user-facing PR) or `create` (the entry is required, creating the file). `workit pr create` enforces it."
94
+ },
95
+ "docs": {
96
+ "type": "string",
97
+ "enum": ["off", "when-user-facing"],
98
+ "description": "The docs refresh the ship skill does before a PR opens: `off` (default) or `when-user-facing`."
99
+ },
100
+ "changelogPath": {
101
+ "anyOf": [
102
+ {
103
+ "type": "string",
104
+ "pattern": "^(?![\\\\/]|[A-Za-z]:)(?!(?:.*[\\\\/])?\\.\\.(?:[\\\\/]|$)).*\\S",
105
+ "description": "A repo-relative changelog path or glob."
106
+ },
107
+ {
108
+ "type": "array",
109
+ "minItems": 1,
110
+ "items": {
111
+ "type": "string",
112
+ "pattern": "^(?![\\\\/]|[A-Za-z]:)(?!(?:.*[\\\\/])?\\.\\.(?:[\\\\/]|$)).*\\S",
113
+ "description": "A repo-relative changelog path or glob."
114
+ }
115
+ }
116
+ ],
117
+ "description": "Where the changelog lives, repo-relative: one path or glob, or a list (a monorepo with one changelog per package; any of them satisfies the gate). Default CHANGELOG.md at the repo root."
118
+ },
119
+ "prTemplate": {
120
+ "anyOf": [
121
+ {
122
+ "type": "string",
123
+ "enum": ["auto", "repo", "workit"]
124
+ },
125
+ {
126
+ "type": "string",
127
+ "pattern": "^(?![\\\\/]|[A-Za-z]:)(?!(?:.*[\\\\/])?\\.\\.(?:[\\\\/]|$)).*\\S.*\\.[mM][dD]$",
128
+ "description": "A repo-relative path to one .md template."
129
+ }
130
+ ],
131
+ "description": "Which template a PR description fills: `auto` (default: the repo's GitHub/GitLab template, else Workit's), `repo` (the repo's, refused when it has none), `workit` (Workit's Summary/Evidence/Merge danger) or a repo-relative path to one `.md` file."
132
+ },
133
+ "releaseNotes": {
134
+ "type": "string",
135
+ "enum": ["auto", "off", "review"],
136
+ "description": "The release notes `workit release finish` publishes on the forge release: `auto` (default: the draft when there is one, else the notes built from the version's changelog section), `off` (no forge release) or `review` (finish refuses until `workit release notes approve`). A release track overrides it."
137
+ },
138
+ "trailers": {
139
+ "description": "Whether commits get the `Workit-Session:` trailer (default true). With false, authorship lives in the ledger only.",
140
+ "type": "boolean"
141
+ },
142
+ "deleteBranch": {
143
+ "description": "Whether `workit pr merge` deletes the head branch after a merge (default true); `--keep-branch` opts out for one merge.",
144
+ "type": "boolean"
145
+ },
146
+ "liveSessionGuard": {
147
+ "description": "Whether the live-session guard denies edits in a checkout another live agent session owns (default true).",
148
+ "type": "boolean"
149
+ },
150
+ "fanout": {
151
+ "description": "Fanout settings.",
152
+ "type": "object",
153
+ "properties": {
154
+ "tierModels": {
155
+ "type": "object",
156
+ "properties": {
157
+ "mundane": {
158
+ "$ref": "#/definitions/tierModel"
159
+ },
160
+ "standard": {
161
+ "$ref": "#/definitions/tierModel"
162
+ },
163
+ "hard": {
164
+ "$ref": "#/definitions/tierModel"
165
+ }
166
+ },
167
+ "additionalProperties": false,
168
+ "description": "The model per slice TIER (mundane, standard, hard), as one name or per host."
169
+ }
170
+ },
171
+ "additionalProperties": false
172
+ },
173
+ "models": {
174
+ "description": "Model and effort per role and host (roles), the lead's own advisory model (lead) and whether a model the lead names on a spawn wins (allowLeadOverride, default false); the same key at the top of workspaces.json is the global default.",
175
+ "type": "object",
176
+ "properties": {
177
+ "roles": {
178
+ "type": "object",
179
+ "properties": {
180
+ "decider": {
181
+ "$ref": "#/definitions/roleModel"
182
+ },
183
+ "implementer": {
184
+ "type": "object",
185
+ "properties": {
186
+ "mundane": {
187
+ "$ref": "#/definitions/roleModel"
188
+ },
189
+ "standard": {
190
+ "$ref": "#/definitions/roleModel"
191
+ },
192
+ "hard": {
193
+ "$ref": "#/definitions/roleModel"
194
+ }
195
+ },
196
+ "additionalProperties": false
197
+ },
198
+ "verifier": {
199
+ "$ref": "#/definitions/roleModel"
200
+ },
201
+ "reviewer": {
202
+ "$ref": "#/definitions/roleModel"
203
+ },
204
+ "explore": {
205
+ "$ref": "#/definitions/roleModel"
206
+ },
207
+ "babysit": {
208
+ "$ref": "#/definitions/roleModel"
209
+ },
210
+ "default": {
211
+ "$ref": "#/definitions/roleModel"
212
+ }
213
+ },
214
+ "additionalProperties": false,
215
+ "description": "Per role (decider, implementer, verifier, reviewer, explore, babysit, default for a general-purpose spawn): a model name, `{ model, effort }`, or one of those per host (claude_code, opencode, codex, codex_cli, codex_desktop, cursor, pi, default). The implementer takes one per tier (mundane, standard, hard)."
216
+ },
217
+ "lead": {
218
+ "$ref": "#/definitions/roleModel",
219
+ "description": "The lead's own model per host, or a list in fallback order; advisory (Workit cannot set a session's model, it prints a switch notice when the lead's provider hits its usage limit)."
220
+ },
221
+ "allowLeadOverride": {
222
+ "type": "boolean",
223
+ "description": "True lets a model the lead names on a spawn win over the configured role model (default false)."
224
+ },
225
+ "limitWindow": {
226
+ "anyOf": [
227
+ {
228
+ "type": "string",
229
+ "pattern": "^\\s*(\\d+(\\.\\d+)?\\s*[dhms]\\s*)+$"
230
+ },
231
+ {
232
+ "type": "number",
233
+ "exclusiveMinimum": 0
234
+ }
235
+ ],
236
+ "description": "How long a provider stays exhausted after a usage limit that names no reset time: a duration (5h, 1d 12h) or hours (default 5h)."
237
+ }
238
+ },
239
+ "additionalProperties": false
240
+ },
241
+ "resources": {
242
+ "type": "object",
243
+ "properties": {
244
+ "slots": {
245
+ "type": "integer",
246
+ "minimum": 1,
247
+ "maximum": 64,
248
+ "description": "How many heavy checks may run at once on this machine."
249
+ },
250
+ "scope": {
251
+ "type": "boolean",
252
+ "description": "False turns the systemd scope off (the lease still applies)."
253
+ },
254
+ "heavy": {
255
+ "type": "array",
256
+ "items": {
257
+ "type": "string"
258
+ },
259
+ "description": "Named checks that are heavy."
260
+ },
261
+ "light": {
262
+ "type": "array",
263
+ "items": {
264
+ "type": "string"
265
+ },
266
+ "description": "Named checks that never take the lease."
267
+ },
268
+ "memoryMax": {
269
+ "type": ["string", "number"],
270
+ "description": "MemoryMax of a heavy check's scope: a percent of RAM (\"40%\") or a size (\"8G\")."
271
+ },
272
+ "cpuQuota": {
273
+ "type": ["string", "number"],
274
+ "description": "CPUQuota of a heavy check's scope."
275
+ },
276
+ "wait": {
277
+ "type": ["number", "string"],
278
+ "description": "How long a heavy check waits for the lease (seconds, or a duration)."
279
+ }
280
+ },
281
+ "additionalProperties": false,
282
+ "description": "Heavy-check limits on this machine: slots, scope, heavy, light, memoryMax, cpuQuota, wait."
283
+ },
284
+ "remotes": {
285
+ "description": "Remote URLs this entry owns: a checkout pushing to or opening PRs on one never exceeds this entry's grants, wherever the folder is (`owner/*` claims a whole owner). Only the user changes it, in their own terminal.",
286
+ "type": "array",
287
+ "items": {
288
+ "type": "string"
289
+ }
290
+ },
291
+ "autonomy": {
292
+ "description": "Autonomy grants (D15): only ever set here, by the user, with `workit grant set`.",
293
+ "type": "object",
294
+ "properties": {
295
+ "push": {
296
+ "description": "The push grant: true, false, or \"verified\" (only after a verdict).",
297
+ "anyOf": [
298
+ {
299
+ "type": "boolean"
300
+ },
301
+ {
302
+ "type": "string",
303
+ "const": "verified"
304
+ }
305
+ ]
306
+ },
307
+ "pr": {
308
+ "description": "The pr grant: true, false, or \"verified\" (only after a verdict).",
309
+ "anyOf": [
310
+ {
311
+ "type": "boolean"
312
+ },
313
+ {
314
+ "type": "string",
315
+ "const": "verified"
316
+ }
317
+ ]
318
+ },
319
+ "merge": {
320
+ "description": "The merge grant: true, false, or \"verified\" (only after a verdict).",
321
+ "anyOf": [
322
+ {
323
+ "type": "boolean"
324
+ },
325
+ {
326
+ "type": "string",
327
+ "const": "verified"
328
+ }
329
+ ]
330
+ },
331
+ "release": {
332
+ "description": "The release grant: true, false, or \"verified\" (only after a verdict).",
333
+ "anyOf": [
334
+ {
335
+ "type": "boolean"
336
+ },
337
+ {
338
+ "type": "string",
339
+ "const": "verified"
340
+ }
341
+ ]
342
+ },
343
+ "rerun": {
344
+ "description": "The rerun grant: true, false, or \"verified\" (only after a verdict).",
345
+ "anyOf": [
346
+ {
347
+ "type": "boolean"
348
+ },
349
+ {
350
+ "type": "string",
351
+ "const": "verified"
352
+ }
353
+ ]
354
+ }
355
+ },
356
+ "additionalProperties": false
357
+ },
358
+ "youtrack": {
359
+ "description": "YouTrack settings for this workspace.",
360
+ "type": "object",
361
+ "properties": {
362
+ "baseUrl": {
363
+ "description": "This workspace's YouTrack URL.",
364
+ "type": "string",
365
+ "pattern": "\\S"
366
+ },
367
+ "link_issues": {
368
+ "description": "Legacy alias of `issues: { provider: youtrack, link: true }`.",
369
+ "type": "boolean"
370
+ }
371
+ },
372
+ "additionalProperties": false
373
+ },
374
+ "issues": {
375
+ "description": "The issue tracker PRs link to (any forge with any tracker).",
376
+ "type": "object",
377
+ "properties": {
378
+ "provider": {
379
+ "description": "The issue tracker PRs link to.",
380
+ "type": "string",
381
+ "enum": ["github", "gitlab", "youtrack"]
382
+ },
383
+ "link": {
384
+ "description": "Derive the issue from the branch name.",
385
+ "type": "boolean"
386
+ },
387
+ "relation": {
388
+ "type": "string",
389
+ "enum": ["closes", "refs"],
390
+ "description": "How a PR names its issue: `closes` (default) or `refs`."
391
+ },
392
+ "backlink": {
393
+ "description": "Post the PR URL on each linked issue after the PR is opened.",
394
+ "type": "boolean"
395
+ },
396
+ "link_on_pr": {
397
+ "description": "Legacy alias of `link`.",
398
+ "type": "boolean"
399
+ },
400
+ "repo": {
401
+ "type": "string",
402
+ "description": "The GitHub/GitLab repository (owner/name) that holds the issues; default the PR's own."
403
+ },
404
+ "host": {
405
+ "type": "string",
406
+ "pattern": "\\S",
407
+ "description": "That repository's host; default the PR's host, or the tracker's public one."
408
+ }
409
+ },
410
+ "additionalProperties": false
411
+ },
412
+ "branchPolicy": {
413
+ "description": "Which branches may be created and which are protected.",
414
+ "type": "object",
415
+ "properties": {
416
+ "preset": {
417
+ "type": "string",
418
+ "enum": ["gitflow", "github-flow", "trunk-based", "custom"],
419
+ "description": "The branch model: gitflow, github-flow, trunk-based or custom (allowed/protected set by hand)."
420
+ },
421
+ "developBranch": {
422
+ "description": "The integration branch gitflow uses (default develop).",
423
+ "type": "string",
424
+ "pattern": "\\S"
425
+ },
426
+ "prefixes": {
427
+ "description": "The branch prefix per kind (feature/, bugfix/, release/, hotfix/).",
428
+ "type": "object",
429
+ "properties": {
430
+ "feature": {
431
+ "type": "string",
432
+ "pattern": "\\S"
433
+ },
434
+ "bugfix": {
435
+ "type": "string",
436
+ "pattern": "\\S"
437
+ },
438
+ "release": {
439
+ "type": "string",
440
+ "pattern": "\\S"
441
+ },
442
+ "hotfix": {
443
+ "type": "string",
444
+ "pattern": "\\S"
445
+ }
446
+ },
447
+ "required": ["feature", "bugfix", "release", "hotfix"],
448
+ "additionalProperties": {}
449
+ },
450
+ "allowed": {
451
+ "description": "Branch name globs a new branch must match (`feature/*`).",
452
+ "type": "array",
453
+ "items": {
454
+ "type": "string",
455
+ "pattern": "\\S"
456
+ }
457
+ },
458
+ "protected": {
459
+ "description": "Branches nobody commits or pushes to directly.",
460
+ "type": "array",
461
+ "items": {
462
+ "type": "string",
463
+ "pattern": "\\S"
464
+ }
465
+ },
466
+ "integration": {
467
+ "description": "How work reaches its base: `pr` (default) opens a PR, `merge` merges locally.",
468
+ "type": "string",
469
+ "enum": ["pr", "merge"]
470
+ }
471
+ },
472
+ "required": ["preset"],
473
+ "additionalProperties": false
474
+ },
475
+ "commitPolicy": {
476
+ "description": "The commit message rules.",
477
+ "type": "object",
478
+ "properties": {
479
+ "preset": {
480
+ "type": "string",
481
+ "enum": ["conventional", "gitmoji", "ticket-prefix", "freeform", "custom", "auto"],
482
+ "description": "The commit message flavor, e.g. conventional."
483
+ },
484
+ "pattern": {
485
+ "description": "A regular expression every commit subject must match.",
486
+ "type": "string"
487
+ }
488
+ },
489
+ "required": ["preset"],
490
+ "additionalProperties": false
491
+ },
492
+ "defaultProfile": {
493
+ "description": "The profile used when none is named; must be a key of `profiles`.",
494
+ "type": "string",
495
+ "pattern": "\\S"
496
+ },
497
+ "profiles": {
498
+ "description": "Named branch/commit policy variants of this workspace.",
499
+ "type": "object",
500
+ "propertyNames": {
501
+ "type": "string",
502
+ "pattern": "\\S"
503
+ },
504
+ "additionalProperties": {
505
+ "type": "object",
506
+ "properties": {
507
+ "branchPolicy": {
508
+ "description": "This profile's branch policy.",
509
+ "type": "object",
510
+ "properties": {
511
+ "preset": {
512
+ "type": "string",
513
+ "enum": ["gitflow", "github-flow", "trunk-based", "custom"],
514
+ "description": "The branch model: gitflow, github-flow, trunk-based or custom (allowed/protected set by hand)."
515
+ },
516
+ "developBranch": {
517
+ "description": "The integration branch gitflow uses (default develop).",
518
+ "type": "string",
519
+ "pattern": "\\S"
520
+ },
521
+ "prefixes": {
522
+ "description": "The branch prefix per kind (feature/, bugfix/, release/, hotfix/).",
523
+ "type": "object",
524
+ "properties": {
525
+ "feature": {
526
+ "type": "string",
527
+ "pattern": "\\S"
528
+ },
529
+ "bugfix": {
530
+ "type": "string",
531
+ "pattern": "\\S"
532
+ },
533
+ "release": {
534
+ "type": "string",
535
+ "pattern": "\\S"
536
+ },
537
+ "hotfix": {
538
+ "type": "string",
539
+ "pattern": "\\S"
540
+ }
541
+ },
542
+ "required": ["feature", "bugfix", "release", "hotfix"],
543
+ "additionalProperties": {}
544
+ },
545
+ "allowed": {
546
+ "description": "Branch name globs a new branch must match (`feature/*`).",
547
+ "type": "array",
548
+ "items": {
549
+ "type": "string",
550
+ "pattern": "\\S"
551
+ }
552
+ },
553
+ "protected": {
554
+ "description": "Branches nobody commits or pushes to directly.",
555
+ "type": "array",
556
+ "items": {
557
+ "type": "string",
558
+ "pattern": "\\S"
559
+ }
560
+ },
561
+ "integration": {
562
+ "description": "How work reaches its base: `pr` (default) opens a PR, `merge` merges locally.",
563
+ "type": "string",
564
+ "enum": ["pr", "merge"]
565
+ }
566
+ },
567
+ "required": ["preset"],
568
+ "additionalProperties": false
569
+ },
570
+ "commitPolicy": {
571
+ "description": "This profile's commit policy.",
572
+ "type": "object",
573
+ "properties": {
574
+ "preset": {
575
+ "type": "string",
576
+ "enum": [
577
+ "conventional",
578
+ "gitmoji",
579
+ "ticket-prefix",
580
+ "freeform",
581
+ "custom",
582
+ "auto"
583
+ ],
584
+ "description": "The commit message flavor, e.g. conventional."
585
+ },
586
+ "pattern": {
587
+ "description": "A regular expression every commit subject must match.",
588
+ "type": "string"
589
+ }
590
+ },
591
+ "required": ["preset"],
592
+ "additionalProperties": false
593
+ }
594
+ },
595
+ "additionalProperties": false
596
+ }
597
+ },
598
+ "releaseTracks": {
599
+ "description": "Named release tracks: production and integration branches, naming and versioning.",
600
+ "type": "object",
601
+ "propertyNames": {
602
+ "type": "string",
603
+ "pattern": "\\S"
604
+ },
605
+ "additionalProperties": {
606
+ "type": "object",
607
+ "properties": {
608
+ "strategy": {
609
+ "description": "The branch model this track follows.",
610
+ "type": "string",
611
+ "enum": ["gitflow", "github-flow", "trunk-based", "custom"]
612
+ },
613
+ "productionBranch": {
614
+ "type": "string",
615
+ "description": "The branch releases land on (main).",
616
+ "pattern": "\\S"
617
+ },
618
+ "integrationBranch": {
619
+ "type": "string",
620
+ "description": "The branch work integrates into (develop).",
621
+ "pattern": "\\S"
622
+ },
623
+ "naming": {
624
+ "description": "Branch name templates per kind, e.g. `feature/{name}`.",
625
+ "type": "object",
626
+ "properties": {
627
+ "feature": {
628
+ "type": "string",
629
+ "pattern": "\\S"
630
+ },
631
+ "release": {
632
+ "type": "string",
633
+ "pattern": "\\S"
634
+ },
635
+ "hotfix": {
636
+ "type": "string",
637
+ "pattern": "\\S"
638
+ }
639
+ },
640
+ "additionalProperties": {}
641
+ },
642
+ "baseBranch": {
643
+ "description": "The branch new work starts from.",
644
+ "type": "string",
645
+ "pattern": "\\S"
646
+ },
647
+ "mergeBackBranches": {
648
+ "description": "Branches a finished release or hotfix is merged back into.",
649
+ "type": "array",
650
+ "items": {
651
+ "type": "string",
652
+ "pattern": "\\S"
653
+ }
654
+ },
655
+ "pullRequestTarget": {
656
+ "description": "The branch PRs target.",
657
+ "type": "string",
658
+ "pattern": "\\S"
659
+ },
660
+ "tagNamespace": {
661
+ "description": "A prefix for this track's release tags.",
662
+ "type": "string"
663
+ },
664
+ "versionSource": {
665
+ "description": "Where the version comes from: package-json, git-tag or manual.",
666
+ "oneOf": [
667
+ {
668
+ "type": "object",
669
+ "properties": {
670
+ "kind": {
671
+ "type": "string",
672
+ "const": "package-json"
673
+ },
674
+ "path": {
675
+ "type": "string",
676
+ "pattern": "\\S"
677
+ },
678
+ "field": {
679
+ "type": "string",
680
+ "pattern": "\\S"
681
+ }
682
+ },
683
+ "required": ["kind", "path", "field"],
684
+ "additionalProperties": false
685
+ },
686
+ {
687
+ "type": "object",
688
+ "properties": {
689
+ "kind": {
690
+ "type": "string",
691
+ "const": "git-tag"
692
+ }
693
+ },
694
+ "required": ["kind"],
695
+ "additionalProperties": false
696
+ },
697
+ {
698
+ "type": "object",
699
+ "properties": {
700
+ "kind": {
701
+ "type": "string",
702
+ "const": "manual"
703
+ }
704
+ },
705
+ "required": ["kind"],
706
+ "additionalProperties": false
707
+ }
708
+ ]
709
+ },
710
+ "requiredChecks": {
711
+ "description": "CI checks that must pass before a release.",
712
+ "type": "array",
713
+ "items": {
714
+ "type": "string",
715
+ "pattern": "\\S"
716
+ }
717
+ },
718
+ "critical": {
719
+ "description": "Fields an older Workit must not ignore: when one is unknown or malformed, Workit fails closed.",
720
+ "type": "array",
721
+ "items": {
722
+ "type": "string",
723
+ "pattern": "\\S"
724
+ }
725
+ },
726
+ "releaseNotes": {
727
+ "type": "string",
728
+ "enum": ["auto", "off", "review"],
729
+ "description": "This track's release notes mode, over the workspace's `releaseNotes`."
730
+ }
731
+ },
732
+ "required": ["productionBranch", "integrationBranch"],
733
+ "additionalProperties": false
734
+ }
735
+ }
736
+ },
737
+ "required": ["name", "glob"],
738
+ "additionalProperties": false
739
+ }
740
+ },
741
+ "models": {
742
+ "description": "The global default model and effort per role and host (roles), the lead's own advisory model (lead) and whether a model the lead names on a spawn wins (allowLeadOverride, default false).",
743
+ "type": "object",
744
+ "properties": {
745
+ "roles": {
746
+ "type": "object",
747
+ "properties": {
748
+ "decider": {
749
+ "$ref": "#/definitions/roleModel"
750
+ },
751
+ "implementer": {
752
+ "type": "object",
753
+ "properties": {
754
+ "mundane": {
755
+ "$ref": "#/definitions/roleModel"
756
+ },
757
+ "standard": {
758
+ "$ref": "#/definitions/roleModel"
759
+ },
760
+ "hard": {
761
+ "$ref": "#/definitions/roleModel"
762
+ }
763
+ },
764
+ "additionalProperties": false
765
+ },
766
+ "verifier": {
767
+ "$ref": "#/definitions/roleModel"
768
+ },
769
+ "reviewer": {
770
+ "$ref": "#/definitions/roleModel"
771
+ },
772
+ "explore": {
773
+ "$ref": "#/definitions/roleModel"
774
+ },
775
+ "babysit": {
776
+ "$ref": "#/definitions/roleModel"
777
+ },
778
+ "default": {
779
+ "$ref": "#/definitions/roleModel"
780
+ }
781
+ },
782
+ "additionalProperties": false,
783
+ "description": "Per role (decider, implementer, verifier, reviewer, explore, babysit, default for a general-purpose spawn): a model name, `{ model, effort }`, or one of those per host (claude_code, opencode, codex, codex_cli, codex_desktop, cursor, pi, default). The implementer takes one per tier (mundane, standard, hard)."
784
+ },
785
+ "lead": {
786
+ "$ref": "#/definitions/roleModel",
787
+ "description": "The lead's own model per host, or a list in fallback order; advisory (Workit cannot set a session's model, it prints a switch notice when the lead's provider hits its usage limit)."
788
+ },
789
+ "allowLeadOverride": {
790
+ "type": "boolean",
791
+ "description": "True lets a model the lead names on a spawn win over the configured role model (default false)."
792
+ },
793
+ "limitWindow": {
794
+ "anyOf": [
795
+ {
796
+ "type": "string",
797
+ "pattern": "^\\s*(\\d+(\\.\\d+)?\\s*[dhms]\\s*)+$"
798
+ },
799
+ {
800
+ "type": "number",
801
+ "exclusiveMinimum": 0
802
+ }
803
+ ],
804
+ "description": "How long a provider stays exhausted after a usage limit that names no reset time: a duration (5h, 1d 12h) or hours (default 5h)."
805
+ }
806
+ },
807
+ "additionalProperties": false
808
+ }
809
+ },
810
+ "additionalProperties": false,
811
+ "definitions": {
812
+ "roleModel": {
813
+ "anyOf": [
814
+ {
815
+ "$ref": "#/definitions/modelLeaf"
816
+ },
817
+ {
818
+ "$ref": "#/definitions/modelList"
819
+ },
820
+ {
821
+ "type": "object",
822
+ "properties": {
823
+ "claude_code": {
824
+ "anyOf": [
825
+ {
826
+ "$ref": "#/definitions/modelLeaf"
827
+ },
828
+ {
829
+ "$ref": "#/definitions/modelList"
830
+ }
831
+ ]
832
+ },
833
+ "opencode": {
834
+ "anyOf": [
835
+ {
836
+ "$ref": "#/definitions/modelLeaf"
837
+ },
838
+ {
839
+ "$ref": "#/definitions/modelList"
840
+ }
841
+ ]
842
+ },
843
+ "codex": {
844
+ "anyOf": [
845
+ {
846
+ "$ref": "#/definitions/modelLeaf"
847
+ },
848
+ {
849
+ "$ref": "#/definitions/modelList"
850
+ }
851
+ ]
852
+ },
853
+ "codex_cli": {
854
+ "anyOf": [
855
+ {
856
+ "$ref": "#/definitions/modelLeaf"
857
+ },
858
+ {
859
+ "$ref": "#/definitions/modelList"
860
+ }
861
+ ]
862
+ },
863
+ "codex_desktop": {
864
+ "anyOf": [
865
+ {
866
+ "$ref": "#/definitions/modelLeaf"
867
+ },
868
+ {
869
+ "$ref": "#/definitions/modelList"
870
+ }
871
+ ]
872
+ },
873
+ "cursor": {
874
+ "anyOf": [
875
+ {
876
+ "$ref": "#/definitions/modelLeaf"
877
+ },
878
+ {
879
+ "$ref": "#/definitions/modelList"
880
+ }
881
+ ]
882
+ },
883
+ "pi": {
884
+ "anyOf": [
885
+ {
886
+ "$ref": "#/definitions/modelLeaf"
887
+ },
888
+ {
889
+ "$ref": "#/definitions/modelList"
890
+ }
891
+ ]
892
+ },
893
+ "default": {
894
+ "anyOf": [
895
+ {
896
+ "$ref": "#/definitions/modelLeaf"
897
+ },
898
+ {
899
+ "$ref": "#/definitions/modelList"
900
+ }
901
+ ]
902
+ }
903
+ },
904
+ "additionalProperties": false
905
+ },
906
+ {
907
+ "type": "array",
908
+ "minItems": 1,
909
+ "items": {
910
+ "anyOf": [
911
+ {
912
+ "$ref": "#/definitions/modelLeaf"
913
+ },
914
+ {
915
+ "type": "object",
916
+ "properties": {
917
+ "claude_code": {
918
+ "$ref": "#/definitions/modelLeaf"
919
+ },
920
+ "opencode": {
921
+ "$ref": "#/definitions/modelLeaf"
922
+ },
923
+ "codex": {
924
+ "$ref": "#/definitions/modelLeaf"
925
+ },
926
+ "codex_cli": {
927
+ "$ref": "#/definitions/modelLeaf"
928
+ },
929
+ "codex_desktop": {
930
+ "$ref": "#/definitions/modelLeaf"
931
+ },
932
+ "cursor": {
933
+ "$ref": "#/definitions/modelLeaf"
934
+ },
935
+ "pi": {
936
+ "$ref": "#/definitions/modelLeaf"
937
+ },
938
+ "default": {
939
+ "$ref": "#/definitions/modelLeaf"
940
+ }
941
+ },
942
+ "additionalProperties": false
943
+ }
944
+ ]
945
+ },
946
+ "description": "Models in fallback order, each for every host or per host: the first whose provider has not hit its usage limit runs."
947
+ }
948
+ ]
949
+ },
950
+ "tierModel": {
951
+ "anyOf": [
952
+ {
953
+ "type": "string",
954
+ "pattern": "\\S"
955
+ },
956
+ {
957
+ "type": "object",
958
+ "properties": {
959
+ "claude_code": {
960
+ "type": "string",
961
+ "pattern": "\\S"
962
+ },
963
+ "opencode": {
964
+ "type": "string",
965
+ "pattern": "\\S"
966
+ },
967
+ "codex": {
968
+ "type": "string",
969
+ "pattern": "\\S"
970
+ },
971
+ "codex_cli": {
972
+ "type": "string",
973
+ "pattern": "\\S"
974
+ },
975
+ "codex_desktop": {
976
+ "type": "string",
977
+ "pattern": "\\S"
978
+ },
979
+ "cursor": {
980
+ "type": "string",
981
+ "pattern": "\\S"
982
+ },
983
+ "pi": {
984
+ "type": "string",
985
+ "pattern": "\\S"
986
+ },
987
+ "default": {
988
+ "type": "string",
989
+ "pattern": "\\S"
990
+ }
991
+ },
992
+ "additionalProperties": false
993
+ }
994
+ ]
995
+ },
996
+ "modelLeaf": {
997
+ "anyOf": [
998
+ {
999
+ "type": "string",
1000
+ "pattern": "\\S",
1001
+ "description": "A model name."
1002
+ },
1003
+ {
1004
+ "type": "object",
1005
+ "properties": {
1006
+ "model": {
1007
+ "type": "string",
1008
+ "description": "The model name."
1009
+ },
1010
+ "effort": {
1011
+ "type": "string",
1012
+ "description": "The reasoning effort."
1013
+ }
1014
+ },
1015
+ "required": ["model"],
1016
+ "additionalProperties": false
1017
+ }
1018
+ ]
1019
+ },
1020
+ "modelList": {
1021
+ "type": "array",
1022
+ "minItems": 1,
1023
+ "items": {
1024
+ "$ref": "#/definitions/modelLeaf"
1025
+ },
1026
+ "description": "Models in fallback order: the first whose provider has not hit its usage limit runs."
1027
+ }
1028
+ }
1029
+ }