@brainervirus/workit-core 0.10.0 → 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.
- package/README.md +5 -3
- package/package.json +8 -3
- package/scripts/analyze-release-scope.ts +4 -1
- package/scripts/doctor-check.ts +3 -1
- package/scripts/install-codex-plugin.sh +28 -0
- package/scripts/install-cursor-plugin.sh +1 -0
- package/scripts/install-opencode-plugin.sh +1 -0
- package/scripts/install-pi-package.sh +56 -0
- package/scripts/rewrite-workspace-deps.ts +22 -5
- package/scripts/sync-release-manifests.ts +8 -5
- package/scripts/sync-runtime.sh +7 -3
- package/scripts/validate-cursor-marketplace.ts +16 -62
- package/skills/workit-babysit/SKILL.md +33 -0
- package/skills/workit-behavioral-tdd/SKILL.md +53 -0
- package/skills/workit-blast-radius/SKILL.md +31 -0
- package/skills/workit-challenge/SKILL.md +62 -0
- package/skills/workit-debug/SKILL.md +61 -0
- package/skills/workit-deslop/SKILL.md +36 -0
- package/skills/workit-diagram/SKILL.md +32 -0
- package/skills/workit-green-run/SKILL.md +29 -0
- package/skills/workit-handoff/SKILL.md +43 -0
- package/skills/workit-implement/SKILL.md +46 -0
- package/skills/workit-mockup/SKILL.md +28 -0
- package/skills/workit-plan/SKILL.md +66 -0
- package/skills/workit-review/SKILL.md +60 -0
- package/skills/workit-steer/SKILL.md +32 -0
- package/src/core/authority.ts +918 -0
- package/src/core/boundary.ts +29 -0
- package/src/core/branch.ts +26 -255
- package/src/core/changelog.ts +95 -18
- package/src/core/commit-flavors.ts +65 -0
- package/src/core/config-conversion.ts +183 -0
- package/src/core/config.ts +42 -0
- package/src/core/cutover.ts +721 -0
- package/src/core/detect-hosts.ts +107 -0
- package/src/core/doctor.ts +428 -18
- package/src/core/external-action-effects.ts +1171 -0
- package/src/core/external-action.ts +541 -0
- package/src/core/init.ts +83 -32
- package/src/core/methods.ts +125 -0
- package/src/core/policy-resolver.ts +523 -0
- package/src/core/pr-create.ts +7 -1
- package/src/core/registration.ts +69 -4
- package/src/core/repo-context.ts +59 -1
- package/src/core/setup.ts +28 -0
- package/src/core/skill-manifests.ts +40 -42
- package/src/core/support-matrix.ts +8 -3
- package/src/core/sync-runtime.ts +15 -3
- package/src/core/task-context.ts +179 -0
- package/src/core/task-contract.ts +1136 -0
- package/src/core/task-engine.ts +2562 -0
- package/src/core/task-evaluation.ts +679 -0
- package/src/core/task-store.ts +1071 -0
- package/src/core/tracker-issues.ts +237 -0
- package/src/core/uninstall.ts +67 -3
- package/src/core/vcs-config.ts +53 -22
- package/src/core/workers.ts +166 -0
- package/src/core/workspaces.ts +3 -1
- package/src/core/youtrack-tools.ts +2 -0
- package/src/core/youtrack.ts +145 -10
- package/src/core.ts +126 -0
- package/templates/execution-contract.md +17 -50
- package/templates/plan-template.md +3 -3
- package/templates/spec-template.md +15 -3
- package/templates/workit-contract.md +12 -0
- package/commands/wk-changelog.md +0 -2
- package/commands/wk-commit.md +0 -2
- package/commands/wk-docs-refresh.md +0 -2
- package/commands/wk-handoff.md +0 -2
- package/commands/wk-implement.md +0 -2
- package/commands/wk-init.md +0 -2
- package/commands/wk-issue-update.md +0 -2
- package/commands/wk-meetings.md +0 -2
- package/commands/wk-pr.md +0 -2
- package/commands/wk-release-notes.md +0 -2
- package/commands/wk-status.md +0 -2
- package/commands/wk-verify.md +0 -2
- package/scripts/update-superpowers.sh +0 -82
- package/scripts/vendor-assets.ts +0 -37
- package/skills/wk-changelog/SKILL.md +0 -15
- package/skills/wk-commit/SKILL.md +0 -16
- package/skills/wk-docs-refresh/SKILL.md +0 -15
- package/skills/wk-handoff/SKILL.md +0 -20
- package/skills/wk-implement/SKILL.md +0 -47
- package/skills/wk-init/SKILL.md +0 -31
- package/skills/wk-issue-update/SKILL.md +0 -27
- package/skills/wk-issue-update/references/youtrack-update-style.md +0 -81
- package/skills/wk-meetings/SKILL.md +0 -17
- package/skills/wk-pr/SKILL.md +0 -27
- package/skills/wk-release-notes/SKILL.md +0 -15
- package/skills/wk-status/SKILL.md +0 -16
- package/skills/wk-verify/SKILL.md +0 -16
- package/src/core/detector.ts +0 -239
- package/src/core/flow-state.ts +0 -3048
- package/src/core/handoff-context.ts +0 -136
- package/src/core/handoff-tools.ts +0 -133
- package/src/core/menu.ts +0 -70
- package/src/core/plan-tasks.ts +0 -43
- package/src/core/reminder.ts +0 -124
- package/src/core/sdd.ts +0 -353
- package/src/state.ts +0 -22
- package/templates/superpowers-doc-contract.md +0 -75
- package/vendor/superpowers/skills/brainstorming/SKILL.md +0 -159
- package/vendor/superpowers/skills/brainstorming/scripts/frame-template.html +0 -213
- package/vendor/superpowers/skills/brainstorming/scripts/helper.js +0 -167
- package/vendor/superpowers/skills/brainstorming/scripts/server.cjs +0 -723
- package/vendor/superpowers/skills/brainstorming/scripts/start-server.sh +0 -209
- package/vendor/superpowers/skills/brainstorming/scripts/stop-server.sh +0 -120
- package/vendor/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/vendor/superpowers/skills/brainstorming/visual-companion.md +0 -291
- package/vendor/superpowers/skills/dispatching-parallel-agents/SKILL.md +0 -185
- package/vendor/superpowers/skills/executing-plans/SKILL.md +0 -70
- package/vendor/superpowers/skills/finishing-a-development-branch/SKILL.md +0 -241
- package/vendor/superpowers/skills/receiving-code-review/SKILL.md +0 -213
- package/vendor/superpowers/skills/requesting-code-review/SKILL.md +0 -103
- package/vendor/superpowers/skills/requesting-code-review/code-reviewer.md +0 -172
- package/vendor/superpowers/skills/subagent-driven-development/SKILL.md +0 -426
- package/vendor/superpowers/skills/subagent-driven-development/implementer-prompt.md +0 -139
- package/vendor/superpowers/skills/subagent-driven-development/scripts/review-package +0 -44
- package/vendor/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +0 -22
- package/vendor/superpowers/skills/subagent-driven-development/scripts/task-brief +0 -40
- package/vendor/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +0 -188
- package/vendor/superpowers/skills/systematic-debugging/CREATION-LOG.md +0 -119
- package/vendor/superpowers/skills/systematic-debugging/SKILL.md +0 -296
- package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +0 -158
- package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting.md +0 -115
- package/vendor/superpowers/skills/systematic-debugging/defense-in-depth.md +0 -122
- package/vendor/superpowers/skills/systematic-debugging/find-polluter.sh +0 -63
- package/vendor/superpowers/skills/systematic-debugging/root-cause-tracing.md +0 -169
- package/vendor/superpowers/skills/systematic-debugging/test-academic.md +0 -14
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-1.md +0 -58
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-2.md +0 -68
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-3.md +0 -69
- package/vendor/superpowers/skills/test-driven-development/SKILL.md +0 -371
- package/vendor/superpowers/skills/test-driven-development/testing-anti-patterns.md +0 -299
- package/vendor/superpowers/skills/using-git-worktrees/SKILL.md +0 -202
- package/vendor/superpowers/skills/using-superpowers/SKILL.md +0 -62
- package/vendor/superpowers/skills/using-superpowers/references/antigravity-tools.md +0 -23
- package/vendor/superpowers/skills/using-superpowers/references/codex-tools.md +0 -39
- package/vendor/superpowers/skills/using-superpowers/references/pi-tools.md +0 -16
- package/vendor/superpowers/skills/verification-before-completion/SKILL.md +0 -139
- package/vendor/superpowers/skills/writing-plans/SKILL.md +0 -174
- package/vendor/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
- package/vendor/superpowers/skills/writing-skills/SKILL.md +0 -689
- package/vendor/superpowers/skills/writing-skills/anthropic-best-practices.md +0 -1150
- package/vendor/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/vendor/superpowers/skills/writing-skills/graphviz-conventions.dot +0 -172
- package/vendor/superpowers/skills/writing-skills/persuasion-principles.md +0 -187
- package/vendor/superpowers/skills/writing-skills/render-graphs.js +0 -168
- package/vendor/superpowers/skills/writing-skills/testing-skills-with-subagents.md +0 -384
package/src/core/init.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
3
4
|
import { configDir, isConfigObject } from "./config";
|
|
4
5
|
import { PLUGIN_ROOT } from "./scripts";
|
|
5
6
|
import { writeFileExclusive } from "./safe-write";
|
|
@@ -27,6 +28,28 @@ const isPlaceholder = (text: string): boolean =>
|
|
|
27
28
|
const modeOk = (p: string): boolean =>
|
|
28
29
|
process.platform === "win32" || (fs.statSync(p).mode & 0o777) === 0o600;
|
|
29
30
|
|
|
31
|
+
/** Provider for a fresh vcs.json: explicit env, else origin remote, else null
|
|
32
|
+
* (no silent default — a tool for everyone must not assume a provider). */
|
|
33
|
+
export const resolveInitProvider = (cwd?: string): string | null => {
|
|
34
|
+
const env = process.env.WORKFLOW_VCS_PROVIDER?.trim();
|
|
35
|
+
if (env) return env.toLowerCase();
|
|
36
|
+
const root = cwd ?? process.env.WORKFLOW_WORKSPACE_ROOT ?? process.cwd();
|
|
37
|
+
try {
|
|
38
|
+
const out = spawnSync("git", ["remote", "get-url", "origin"], {
|
|
39
|
+
cwd: root,
|
|
40
|
+
encoding: "utf8",
|
|
41
|
+
});
|
|
42
|
+
if (out.status === 0) {
|
|
43
|
+
const url = (out.stdout ?? "").trim();
|
|
44
|
+
if (/github\.com[:/]/.test(url)) return "github";
|
|
45
|
+
if (/gitlab\.com[:/]/.test(url)) return "gitlab";
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
/* no git: unresolvable, caller omits the field */
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
};
|
|
52
|
+
|
|
30
53
|
const resolvePath = (p: string): string => {
|
|
31
54
|
try {
|
|
32
55
|
return fs.realpathSync(p);
|
|
@@ -161,7 +184,9 @@ export function initStatusData(configDirPath = configDir()): Record<string, any>
|
|
|
161
184
|
let tokenCreateUrls: Record<string, any> | null = null;
|
|
162
185
|
const vcsParsed = readJson(vcsJson);
|
|
163
186
|
if (vcsParsed) {
|
|
164
|
-
const
|
|
187
|
+
const rawProvider = vcsParsed.provider;
|
|
188
|
+
const provider =
|
|
189
|
+
typeof rawProvider === "string" && rawProvider.trim() ? rawProvider.toLowerCase() : null;
|
|
165
190
|
const tokenFiles: Record<string, string> = {};
|
|
166
191
|
for (const k of ["gitlab", "github"]) {
|
|
167
192
|
tokenFiles[k] = String(vcsParsed[k]?.tokenFile ?? path.join(configDirPath, `${k}.token`));
|
|
@@ -261,18 +286,29 @@ export async function toolkitStatusData(configDirPath = configDir()): Promise<Re
|
|
|
261
286
|
const placeholder = Boolean(tokenItem.placeholder);
|
|
262
287
|
|
|
263
288
|
const vcsCfg = (status.vcs_config ?? {}) as Record<string, any>;
|
|
264
|
-
const provider =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
289
|
+
const provider =
|
|
290
|
+
typeof vcsCfg.provider === "string" && vcsCfg.provider.trim()
|
|
291
|
+
? vcsCfg.provider.toLowerCase()
|
|
292
|
+
: null;
|
|
293
|
+
const vcsTokenId =
|
|
294
|
+
provider === "gitlab" ? "gitlab_token" : provider === "github" ? "github_token" : null;
|
|
295
|
+
const vcsTokenItem =
|
|
296
|
+
(vcsTokenId ? status.items.find((i: Record<string, any>) => i.id === vcsTokenId) : null) ?? {};
|
|
297
|
+
const vcsPlaceholder = vcsTokenId ? (vcsTokenItem.placeholder ?? true) : true;
|
|
268
298
|
const vcsJsonOk = Boolean(status.items.find((i: Record<string, any>) => i.id === "vcs_json")?.ok);
|
|
269
299
|
|
|
270
300
|
const verify = placeholder
|
|
271
301
|
? { ok: false, error: "token still placeholder YOUR_TOKEN_HERE" }
|
|
272
302
|
: await youTrackVerifyToken();
|
|
273
|
-
const vcsVerify =
|
|
274
|
-
|
|
275
|
-
|
|
303
|
+
const vcsVerify =
|
|
304
|
+
provider === null
|
|
305
|
+
? {
|
|
306
|
+
ok: false,
|
|
307
|
+
error: "vcs provider unconfigured — set provider to gitlab or github in vcs.json",
|
|
308
|
+
}
|
|
309
|
+
: vcsPlaceholder
|
|
310
|
+
? { ok: false, error: "vcs token still placeholder YOUR_TOKEN_HERE" }
|
|
311
|
+
: await vcsVerifyToken();
|
|
276
312
|
const youTrackHealth = ("data" in verify ? verify.data : verify) as Record<string, any>;
|
|
277
313
|
|
|
278
314
|
status.youtrack_verify = verify;
|
|
@@ -340,27 +376,33 @@ const youtrackJsonContent = (dir: string): Record<string, any> => ({
|
|
|
340
376
|
},
|
|
341
377
|
});
|
|
342
378
|
|
|
343
|
-
const vcsJsonContent = (dir: string): Record<string, any> =>
|
|
344
|
-
provider:
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
379
|
+
const vcsJsonContent = (dir: string, cwd?: string): Record<string, any> => {
|
|
380
|
+
// Explicit provider at init: env wins, else the checkout's origin remote
|
|
381
|
+
// (same RL-03b rule as vcs-config). Unresolvable means the field is
|
|
382
|
+
// omitted — never a silent assumption downstream.
|
|
383
|
+
const provider = resolveInitProvider(cwd);
|
|
384
|
+
return {
|
|
385
|
+
...(provider ? { provider } : {}),
|
|
386
|
+
defaultTargetBranch: process.env.WORKFLOW_VCS_TARGET_BRANCH ?? "develop",
|
|
387
|
+
gitlab: {
|
|
388
|
+
host: process.env.WORKFLOW_GITLAB_HOST ?? "gitlab.com",
|
|
389
|
+
apiUrl: process.env.WORKFLOW_GITLAB_API_URL ?? "https://gitlab.com/api/v4",
|
|
390
|
+
tokenFile: path.join(dir, "gitlab.token"),
|
|
391
|
+
},
|
|
392
|
+
github: {
|
|
393
|
+
host: process.env.WORKFLOW_GITHUB_HOST ?? "github.com",
|
|
394
|
+
tokenFile: path.join(dir, "github.token"),
|
|
395
|
+
},
|
|
396
|
+
pr: { squashOnMerge: true, removeSourceBranch: true, pushBranch: true, confirmSkip: true },
|
|
397
|
+
tokenDefaults: {
|
|
398
|
+
name: "workit",
|
|
399
|
+
description: "OpenCode workit — /wk-pr and glab/gh",
|
|
400
|
+
gitlabScopes: ["api"],
|
|
401
|
+
githubPermissions: { pull_requests: "write", contents: "write", metadata: "read" },
|
|
402
|
+
githubClassicScopes: ["repo"],
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
};
|
|
364
406
|
|
|
365
407
|
/** Port of scripts/init/apply.sh — confirmed scaffold actions. */
|
|
366
408
|
export function initApplyData(
|
|
@@ -466,10 +508,16 @@ export function initApplyData(
|
|
|
466
508
|
process.env.WORKFLOW_VCS_CONFIG = configPath;
|
|
467
509
|
try {
|
|
468
510
|
const cfg = readJson(configPath) ?? {};
|
|
469
|
-
const
|
|
511
|
+
const rawProvider = cfg.provider;
|
|
512
|
+
const provider = typeof rawProvider === "string" && rawProvider.trim() ? rawProvider : null;
|
|
470
513
|
const tokenUrls = vcsTokenCreateUrls();
|
|
471
514
|
const active = tokenUrls.active ?? {};
|
|
472
|
-
const activePath =
|
|
515
|
+
const activePath =
|
|
516
|
+
provider === "gitlab"
|
|
517
|
+
? path.resolve(glPath)
|
|
518
|
+
: provider === "github"
|
|
519
|
+
? path.resolve(ghPath)
|
|
520
|
+
: null;
|
|
473
521
|
return {
|
|
474
522
|
action,
|
|
475
523
|
ok: true,
|
|
@@ -491,7 +539,10 @@ export function initApplyData(
|
|
|
491
539
|
switchHint: 'Change "provider" to "github" when you migrate — token files are separate',
|
|
492
540
|
skill: "/wk-pr",
|
|
493
541
|
},
|
|
494
|
-
instruction:
|
|
542
|
+
instruction:
|
|
543
|
+
provider === null
|
|
544
|
+
? `No provider resolved — set provider to gitlab or github in ${configPath}, then /wk-status.`
|
|
545
|
+
: `Open the create-token URL for ${provider}, click Create, paste into ${activePath}, then /wk-status.`,
|
|
495
546
|
};
|
|
496
547
|
} finally {
|
|
497
548
|
if (prev === undefined) delete process.env.WORKFLOW_VCS_CONFIG;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { Assurance, Capability, Dimension, Policy } from "./task-contract";
|
|
2
|
+
|
|
3
|
+
export type MethodId =
|
|
4
|
+
| "workit-challenge"
|
|
5
|
+
| "workit-behavioral-tdd"
|
|
6
|
+
| "workit-review"
|
|
7
|
+
| "workit-plan"
|
|
8
|
+
| "workit-implement"
|
|
9
|
+
| "workit-debug"
|
|
10
|
+
| "workit-handoff"
|
|
11
|
+
| "workit-deslop";
|
|
12
|
+
|
|
13
|
+
type MethodDefinition = {
|
|
14
|
+
dimensions?: readonly Dimension[];
|
|
15
|
+
ruleIds?: readonly string[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const METHODS: Readonly<Record<MethodId, MethodDefinition>> = {
|
|
19
|
+
"workit-challenge": { dimensions: ["challenge", "decisions"] },
|
|
20
|
+
"workit-behavioral-tdd": { dimensions: ["testing"] },
|
|
21
|
+
"workit-review": { dimensions: ["review"] },
|
|
22
|
+
"workit-plan": { dimensions: ["artifacts", "continuity"] },
|
|
23
|
+
"workit-implement": { dimensions: ["delegation"] },
|
|
24
|
+
"workit-debug": { ruleIds: ["root-cause-investigation"] },
|
|
25
|
+
"workit-handoff": { ruleIds: ["durable-handoff"] },
|
|
26
|
+
"workit-deslop": { ruleIds: ["pre-pr-cleanup"] },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type SelectedMethod = {
|
|
30
|
+
id: MethodId;
|
|
31
|
+
reason: string;
|
|
32
|
+
assurance: Assurance;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const methodMatches = (
|
|
36
|
+
id: MethodId,
|
|
37
|
+
definition: MethodDefinition,
|
|
38
|
+
requirement: Policy["requirements"][number],
|
|
39
|
+
): boolean =>
|
|
40
|
+
(definition.dimensions?.includes(requirement.dimension) === true &&
|
|
41
|
+
!(id === "workit-review" && requirement.ruleId === "self-review")) ||
|
|
42
|
+
definition.ruleIds?.includes(requirement.ruleId) === true;
|
|
43
|
+
|
|
44
|
+
const assuranceFor = (
|
|
45
|
+
id: MethodId,
|
|
46
|
+
definition: MethodDefinition,
|
|
47
|
+
capabilities: Capability[],
|
|
48
|
+
): { assurance: Assurance; reasons: string[] } => {
|
|
49
|
+
const keys = new Set<string>([
|
|
50
|
+
id,
|
|
51
|
+
...(definition.dimensions ?? []),
|
|
52
|
+
...(definition.ruleIds ?? []),
|
|
53
|
+
]);
|
|
54
|
+
const matches = capabilities.filter(
|
|
55
|
+
(capability) => keys.has(capability.name) || keys.has(capability.surface),
|
|
56
|
+
);
|
|
57
|
+
if (id === "workit-review" && matches.length === 0)
|
|
58
|
+
return { assurance: "unavailable", reasons: ["independent review capability is unavailable"] };
|
|
59
|
+
if (matches.some((capability) => capability.assurance === "unavailable"))
|
|
60
|
+
return {
|
|
61
|
+
assurance: "unavailable",
|
|
62
|
+
reasons: matches
|
|
63
|
+
.filter((capability) => capability.assurance === "unavailable")
|
|
64
|
+
.map((capability) => capability.reason),
|
|
65
|
+
};
|
|
66
|
+
if (matches.some((capability) => capability.assurance === "enforced"))
|
|
67
|
+
return { assurance: "enforced", reasons: matches.map((capability) => capability.reason) };
|
|
68
|
+
return { assurance: "agent_guided", reasons: matches.map((capability) => capability.reason) };
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export function selectMethods(policy: Policy, capabilities: Capability[]): SelectedMethod[] {
|
|
72
|
+
return (Object.entries(METHODS) as [MethodId, MethodDefinition][]).flatMap(([id, definition]) => {
|
|
73
|
+
const requirements = policy.requirements.filter((requirement) =>
|
|
74
|
+
methodMatches(id, definition, requirement),
|
|
75
|
+
);
|
|
76
|
+
if (requirements.length === 0) return [];
|
|
77
|
+
const capability = assuranceFor(id, definition, capabilities);
|
|
78
|
+
const reasons = [
|
|
79
|
+
...new Set(requirements.map((requirement) => requirement.reason)),
|
|
80
|
+
...capability.reasons,
|
|
81
|
+
];
|
|
82
|
+
if (capability.assurance === "unavailable")
|
|
83
|
+
reasons.unshift("required capability is unavailable");
|
|
84
|
+
return [{ id, reason: reasons.join("; "), assurance: capability.assurance }];
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const invariantBootstrap = (): string =>
|
|
89
|
+
`
|
|
90
|
+
Workit keeps one accountable lead and one shared task state. Inspect current task
|
|
91
|
+
state before acting. An empty task.list means no session yet, not permission to
|
|
92
|
+
skip Workit; for user-requested product, debug, or behavior work with no active
|
|
93
|
+
or paused task, run task.start then policy.assess before other product mutations.
|
|
94
|
+
Omitted expectedRevision, expectedWorkspaceRevision, and writer workerId default
|
|
95
|
+
to the current records; explicit values are still concurrency-checked, so never
|
|
96
|
+
copy revisions between calls. Happy path: task.list, task.start {intent} with no
|
|
97
|
+
revisions, policy.assess {assessment: {facts, signals, consequences,
|
|
98
|
+
verification}} where facts are inferred or observed with file refs,
|
|
99
|
+
writer.acquire {taskId} before product writes, evidence.record {evidence} where
|
|
100
|
+
check and review kinds auto-bind the current tree and need no digests. Record
|
|
101
|
+
verification evidence last: later evidence or commits can reopen fixed findings
|
|
102
|
+
for re-verification, so verify, resolve, then close with nothing in between.
|
|
103
|
+
decision.record {binding with taskId/workspaceId from inspect plus presented and
|
|
104
|
+
approvedContent} only through a native approval question, task.close {outcome,
|
|
105
|
+
summary, decisionIds}. A completed native subagent run stops its bound worker
|
|
106
|
+
by itself; if a worker strands in cancelling with its run verifiably over,
|
|
107
|
+
repeat worker.cancel {reason} to confirm the stop. Check and review evidence
|
|
108
|
+
without a bound candidate goes stale; findings close only as fixed with passing
|
|
109
|
+
verification, dismissed with supporting evidence, or deferred under an approved
|
|
110
|
+
limitation. Use only the
|
|
111
|
+
shared operations for task, policy, evidence, finding, decision, worker, writer,
|
|
112
|
+
and state changes. Authority is bounded by the requested scope, current
|
|
113
|
+
revision, caller/session provenance, and observed capabilities. Never claim host
|
|
114
|
+
enforcement or evidence that the host cannot provide. Shell-executed writes are
|
|
115
|
+
unattested agent-guided work even when a writer is held. Preserve unresolved
|
|
116
|
+
requirements, gaps, and uncertain workers. Skill routing: slash aliases /wk-*
|
|
117
|
+
always load on demand. Model-invoked: new instructions, interruptions, or
|
|
118
|
+
forgotten items mid-task → load workit-steer before responding; about to open
|
|
119
|
+
a PR or fresh from implementing → load workit-deslop; CI red → load
|
|
120
|
+
workit-green-run; small-looking change before close or merge → load
|
|
121
|
+
workit-blast-radius; ambiguous, consequential, or disputed proposal before
|
|
122
|
+
recommending → load workit-challenge; spec or plan needs a flow diagram →
|
|
123
|
+
load workit-diagram, a UI sketch → load workit-mockup. Load the skill; never
|
|
124
|
+
act from memory of it.
|
|
125
|
+
`.trim();
|