@mku1tra/work 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Kelly
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,322 @@
1
+ /**
2
+ * work: the types of the work, on basis. The work (objectives, issues), the plan that cuts an issue into CLs, and the
3
+ * cl note that carries one cut to the agents that build it: what is tracked, how it nests and what blocks it. Each type
4
+ * has a note in types/ that says what each part of its notes holds, and whose body a new note starts from. It holds no
5
+ * notes: a graph that imports it holds the work, in its own ground. Work can belong to any note.
6
+ */
7
+ import * as z from "zod";
8
+ export declare const work: Readonly<{
9
+ name: "work";
10
+ description: string;
11
+ abstract: boolean;
12
+ parents: readonly [];
13
+ schema: z.ZodObject<{
14
+ type: z.ZodLiteral<"work">;
15
+ name: z.ZodString;
16
+ description: z.ZodString;
17
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
18
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
+ }, z.core.$strict>;
20
+ key: Readonly<readonly [] | never[]>;
21
+ }>;
22
+ export declare const objective: Readonly<{
23
+ name: "objective";
24
+ description: string;
25
+ abstract: boolean;
26
+ parents: readonly [Readonly<{
27
+ name: "work";
28
+ description: string;
29
+ abstract: boolean;
30
+ parents: readonly [];
31
+ schema: z.ZodObject<{
32
+ type: z.ZodLiteral<"work">;
33
+ name: z.ZodString;
34
+ description: z.ZodString;
35
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
36
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
37
+ }, z.core.$strict>;
38
+ key: Readonly<readonly [] | never[]>;
39
+ }>];
40
+ schema: z.ZodObject<{
41
+ type: z.ZodLiteral<"objective">;
42
+ name: z.ZodString;
43
+ description: z.ZodString;
44
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
45
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
46
+ status: z.ZodEnum<{
47
+ draft: "draft";
48
+ active: "active";
49
+ archived: "archived";
50
+ dropped: "dropped";
51
+ }>;
52
+ }, z.core.$strict>;
53
+ key: Readonly<readonly [] | never[]>;
54
+ }>;
55
+ export declare const issue: Readonly<{
56
+ name: "issue";
57
+ description: string;
58
+ abstract: boolean;
59
+ parents: readonly [Readonly<{
60
+ name: "work";
61
+ description: string;
62
+ abstract: boolean;
63
+ parents: readonly [];
64
+ schema: z.ZodObject<{
65
+ type: z.ZodLiteral<"work">;
66
+ name: z.ZodString;
67
+ description: z.ZodString;
68
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
70
+ }, z.core.$strict>;
71
+ key: Readonly<readonly [] | never[]>;
72
+ }>];
73
+ schema: z.ZodObject<{
74
+ type: z.ZodLiteral<"issue">;
75
+ name: z.ZodString;
76
+ description: z.ZodString;
77
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
78
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
79
+ kind: z.ZodEnum<{
80
+ bug: "bug";
81
+ "feature-request": "feature-request";
82
+ "internal-cleanup": "internal-cleanup";
83
+ vulnerability: "vulnerability";
84
+ project: "project";
85
+ epic: "epic";
86
+ feature: "feature";
87
+ milestone: "milestone";
88
+ story: "story";
89
+ task: "task";
90
+ }>;
91
+ priority: z.ZodEnum<{
92
+ P0: "P0";
93
+ P1: "P1";
94
+ P2: "P2";
95
+ P3: "P3";
96
+ P4: "P4";
97
+ }>;
98
+ repo: z.ZodOptional<z.ZodString>;
99
+ status: z.ZodEnum<{
100
+ dropped: "dropped";
101
+ new: "new";
102
+ "in-progress": "in-progress";
103
+ done: "done";
104
+ }>;
105
+ }, z.core.$strict>;
106
+ key: Readonly<readonly [] | never[]>;
107
+ }>;
108
+ export declare const plan: Readonly<{
109
+ name: "plan";
110
+ description: string;
111
+ abstract: boolean;
112
+ parents: readonly [];
113
+ schema: z.ZodObject<{
114
+ type: z.ZodLiteral<"plan">;
115
+ name: z.ZodString;
116
+ description: z.ZodString;
117
+ belongsTo: z.ZodString;
118
+ status: z.ZodEnum<{
119
+ draft: "draft";
120
+ active: "active";
121
+ dropped: "dropped";
122
+ done: "done";
123
+ review: "review";
124
+ }>;
125
+ }, z.core.$strict>;
126
+ key: Readonly<readonly [] | never[]>;
127
+ }>;
128
+ export declare const cl: Readonly<{
129
+ name: "cl";
130
+ description: string;
131
+ abstract: boolean;
132
+ parents: readonly [];
133
+ schema: z.ZodObject<{
134
+ type: z.ZodLiteral<"cl">;
135
+ name: z.ZodString;
136
+ description: z.ZodString;
137
+ belongsTo: z.ZodString;
138
+ phase: z.ZodOptional<z.ZodNumber>;
139
+ repo: z.ZodOptional<z.ZodString>;
140
+ shape: z.ZodOptional<z.ZodObject<{
141
+ change: z.ZodEnum<{
142
+ behavior: "behavior";
143
+ structure: "structure";
144
+ }>;
145
+ checked: z.ZodEnum<{
146
+ repo: "repo";
147
+ system: "system";
148
+ }>;
149
+ }, z.core.$strip>>;
150
+ checkout: z.ZodOptional<z.ZodArray<z.ZodString>>;
151
+ test: z.ZodOptional<z.ZodString>;
152
+ status: z.ZodEnum<{
153
+ dropped: "dropped";
154
+ new: "new";
155
+ "in-progress": "in-progress";
156
+ done: "done";
157
+ }>;
158
+ }, z.core.$strict>;
159
+ key: Readonly<readonly [] | never[]>;
160
+ }>;
161
+ /** A plan's phases are its cls' `phase`, and they run 1, 2, 3 with no gap, so each cl has one. */
162
+ export declare const phases: import("@mku1tra/basis").Rule;
163
+ /** A plan is named for its issue: `<issue>-plan`. */
164
+ export declare const planName: import("@mku1tra/basis").Rule;
165
+ /** A cl is named for its issue and its cut: `<issue>-<cut>`, whether it belongs to the issue's plan or to the issue. */
166
+ export declare const clName: import("@mku1tra/basis").Rule;
167
+ declare const schema: import("@mku1tra/basis").Schema<{
168
+ readonly work: Readonly<{
169
+ name: "work";
170
+ description: string;
171
+ abstract: boolean;
172
+ parents: readonly [];
173
+ schema: z.ZodObject<{
174
+ type: z.ZodLiteral<"work">;
175
+ name: z.ZodString;
176
+ description: z.ZodString;
177
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
178
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
179
+ }, z.core.$strict>;
180
+ key: Readonly<readonly [] | never[]>;
181
+ }>;
182
+ readonly objective: Readonly<{
183
+ name: "objective";
184
+ description: string;
185
+ abstract: boolean;
186
+ parents: readonly [Readonly<{
187
+ name: "work";
188
+ description: string;
189
+ abstract: boolean;
190
+ parents: readonly [];
191
+ schema: z.ZodObject<{
192
+ type: z.ZodLiteral<"work">;
193
+ name: z.ZodString;
194
+ description: z.ZodString;
195
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
196
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
197
+ }, z.core.$strict>;
198
+ key: Readonly<readonly [] | never[]>;
199
+ }>];
200
+ schema: z.ZodObject<{
201
+ type: z.ZodLiteral<"objective">;
202
+ name: z.ZodString;
203
+ description: z.ZodString;
204
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
205
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
206
+ status: z.ZodEnum<{
207
+ draft: "draft";
208
+ active: "active";
209
+ archived: "archived";
210
+ dropped: "dropped";
211
+ }>;
212
+ }, z.core.$strict>;
213
+ key: Readonly<readonly [] | never[]>;
214
+ }>;
215
+ readonly issue: Readonly<{
216
+ name: "issue";
217
+ description: string;
218
+ abstract: boolean;
219
+ parents: readonly [Readonly<{
220
+ name: "work";
221
+ description: string;
222
+ abstract: boolean;
223
+ parents: readonly [];
224
+ schema: z.ZodObject<{
225
+ type: z.ZodLiteral<"work">;
226
+ name: z.ZodString;
227
+ description: z.ZodString;
228
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
229
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
230
+ }, z.core.$strict>;
231
+ key: Readonly<readonly [] | never[]>;
232
+ }>];
233
+ schema: z.ZodObject<{
234
+ type: z.ZodLiteral<"issue">;
235
+ name: z.ZodString;
236
+ description: z.ZodString;
237
+ belongsTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
238
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
239
+ kind: z.ZodEnum<{
240
+ bug: "bug";
241
+ "feature-request": "feature-request";
242
+ "internal-cleanup": "internal-cleanup";
243
+ vulnerability: "vulnerability";
244
+ project: "project";
245
+ epic: "epic";
246
+ feature: "feature";
247
+ milestone: "milestone";
248
+ story: "story";
249
+ task: "task";
250
+ }>;
251
+ priority: z.ZodEnum<{
252
+ P0: "P0";
253
+ P1: "P1";
254
+ P2: "P2";
255
+ P3: "P3";
256
+ P4: "P4";
257
+ }>;
258
+ repo: z.ZodOptional<z.ZodString>;
259
+ status: z.ZodEnum<{
260
+ dropped: "dropped";
261
+ new: "new";
262
+ "in-progress": "in-progress";
263
+ done: "done";
264
+ }>;
265
+ }, z.core.$strict>;
266
+ key: Readonly<readonly [] | never[]>;
267
+ }>;
268
+ readonly plan: Readonly<{
269
+ name: "plan";
270
+ description: string;
271
+ abstract: boolean;
272
+ parents: readonly [];
273
+ schema: z.ZodObject<{
274
+ type: z.ZodLiteral<"plan">;
275
+ name: z.ZodString;
276
+ description: z.ZodString;
277
+ belongsTo: z.ZodString;
278
+ status: z.ZodEnum<{
279
+ draft: "draft";
280
+ active: "active";
281
+ dropped: "dropped";
282
+ done: "done";
283
+ review: "review";
284
+ }>;
285
+ }, z.core.$strict>;
286
+ key: Readonly<readonly [] | never[]>;
287
+ }>;
288
+ readonly cl: Readonly<{
289
+ name: "cl";
290
+ description: string;
291
+ abstract: boolean;
292
+ parents: readonly [];
293
+ schema: z.ZodObject<{
294
+ type: z.ZodLiteral<"cl">;
295
+ name: z.ZodString;
296
+ description: z.ZodString;
297
+ belongsTo: z.ZodString;
298
+ phase: z.ZodOptional<z.ZodNumber>;
299
+ repo: z.ZodOptional<z.ZodString>;
300
+ shape: z.ZodOptional<z.ZodObject<{
301
+ change: z.ZodEnum<{
302
+ behavior: "behavior";
303
+ structure: "structure";
304
+ }>;
305
+ checked: z.ZodEnum<{
306
+ repo: "repo";
307
+ system: "system";
308
+ }>;
309
+ }, z.core.$strip>>;
310
+ checkout: z.ZodOptional<z.ZodArray<z.ZodString>>;
311
+ test: z.ZodOptional<z.ZodString>;
312
+ status: z.ZodEnum<{
313
+ dropped: "dropped";
314
+ new: "new";
315
+ "in-progress": "in-progress";
316
+ done: "done";
317
+ }>;
318
+ }, z.core.$strict>;
319
+ key: Readonly<readonly [] | never[]>;
320
+ }>;
321
+ }, readonly []>;
322
+ export default schema;
package/dist/schema.js ADDED
@@ -0,0 +1,179 @@
1
+ /**
2
+ * work: the types of the work, on basis. The work (objectives, issues), the plan that cuts an issue into CLs, and the
3
+ * cl note that carries one cut to the agents that build it: what is tracked, how it nests and what blocks it. Each type
4
+ * has a note in types/ that says what each part of its notes holds, and whose body a new note starts from. It holds no
5
+ * notes: a graph that imports it holds the work, in its own ground. Work can belong to any note.
6
+ */
7
+ import { defineRule, defineSchema, defineType, manyOrNone, one, } from "@mku1tra/basis";
8
+ import * as z from "zod";
9
+ export const work = defineType({
10
+ name: "work",
11
+ description: "A tracked piece of work: where it belongs, and what blocks it. Abstract: a note is of a type that inherits it.",
12
+ abstract: true,
13
+ fields: {
14
+ // The one note this is part of, of any type: other work, or a note about the thing it changes, often in another
15
+ // repo. It is the roll-up, not the folder. A plain string, as "[[name]]", so Obsidian still follows it: the graph
16
+ // that holds the work lints alone, so the lint cannot see a note of another repo, and it does not check this.
17
+ belongsTo: z.string().nullable().optional(),
18
+ // What this cannot finish without. Only the obvious dependencies; review catches the implicit ones. The return type
19
+ // is said: objective and issue inherit work, so TypeScript cannot infer a type that names itself.
20
+ dependsOn: manyOrNone(() => [objective, issue]),
21
+ },
22
+ });
23
+ export const objective = defineType({
24
+ name: "objective",
25
+ description: "An end state to reach, with about three key results that show it is reached; issues hang under it. One is active at a time. The key results live in the body.",
26
+ parents: [work],
27
+ fields: {
28
+ status: z
29
+ .enum(["draft", "active", "archived", "dropped"])
30
+ .describe("draft: being written. active: the one being worked toward. archived: reached, or no longer current. dropped: abandoned"),
31
+ },
32
+ });
33
+ export const issue = defineType({
34
+ name: "issue",
35
+ description: "A tracked piece of work, from a bug to a project; every CL points to one. Its kind says which.",
36
+ parents: [work],
37
+ fields: {
38
+ kind: z
39
+ .enum([
40
+ "bug",
41
+ "feature-request",
42
+ "internal-cleanup",
43
+ "vulnerability",
44
+ "project",
45
+ "epic",
46
+ "feature",
47
+ "milestone",
48
+ "story",
49
+ "task",
50
+ ])
51
+ .describe("What the work is (Google Issue Tracker's types). A problem: bug, feature-request, internal-cleanup, vulnerability. A piece of work, big to small: project, epic, feature, milestone, story, task"),
52
+ priority: z
53
+ .enum(["P0", "P1", "P2", "P3", "P4"])
54
+ .describe("How soon it needs doing: P0, now at any cost, to P4, eventually. P2 is the default"),
55
+ // The repo the work changes, as "[[name]]" of its note: a plain string, as belongsTo is, since the repo's note is
56
+ // outside the graph that holds the work, and its lint cannot see it.
57
+ repo: z.string().optional(),
58
+ status: z
59
+ .enum(["new", "in-progress", "done", "dropped"])
60
+ .describe("new: not started. in-progress: claimed, being worked on. done: met, verified, proven where it runs and validated by a person; a controller reaches only verified, so it never sets done. dropped: abandoned, kept for history"),
61
+ },
62
+ });
63
+ export const plan = defineType({
64
+ name: "plan",
65
+ description: "The refinement of one issue, written as an argument: how its cls, in phases, meet the issue's done. Only when the issue takes more than one CL. Draft while it is cut, active once plan-review passes it.",
66
+ fields: {
67
+ // The issue it plans.
68
+ belongsTo: one(() => issue),
69
+ status: z
70
+ .enum(["draft", "review", "active", "done", "dropped"])
71
+ .describe("draft: being cut. review: handed in, waiting for plan-review, and for a person's sign-off when the operator asks for one. active: passed, the cut in force. done: the issue's check is met. dropped: abandoned, kept for history"),
72
+ },
73
+ });
74
+ export const cl = defineType({
75
+ name: "cl",
76
+ description: "The spec of one cut, the CL that builds it, as a contract: its check is what it ensures, its phase what it requires, its seam what it keeps. Its shape, checkout and test command are data; its intent, check, seam and the description of its checkout are prose. The note holds the spec only: what happens to it (its state, attempts, results and findings) is the controller's record, keyed by its name. new once written, done once the CL lands.",
77
+ fields: {
78
+ // The plan it is a cut of, or the issue itself when the issue takes one CL.
79
+ belongsTo: one(() => [plan, issue]),
80
+ phase: z
81
+ .number()
82
+ .int()
83
+ .min(1)
84
+ .optional()
85
+ .describe("Its phase in its plan, from 1: the phases run in order, and the cls of one phase need nothing from each other. None when it is the issue's lone cl"),
86
+ repo: z
87
+ .string()
88
+ .min(1)
89
+ .optional()
90
+ .describe("The repo it changes, by its folder's name: one of its issue's. A CL lands in one repo, so a change across repos is a cl per repo. None when its issue changes one repo"),
91
+ shape: z
92
+ .object({
93
+ change: z
94
+ .enum(["behavior", "structure"])
95
+ .describe("behavior: its check fails before and passes after. structure: its check passes before and after"),
96
+ checked: z
97
+ .enum(["repo", "system"])
98
+ .describe("where its check runs: in the repo, or on the running system"),
99
+ })
100
+ .optional()
101
+ .describe("What the change is, and where its check runs"),
102
+ checkout: z
103
+ .array(z.string().min(1))
104
+ .min(1)
105
+ .optional()
106
+ .describe("The paths its builders get on disk, from its repo's root, as git sparse-checkout patterns: a file, or a folder for all under it. Every path conceivably relevant to the cut, so they start from what the planner found, and its Checkout section says what each is"),
107
+ test: z
108
+ .string()
109
+ .min(1)
110
+ .optional()
111
+ .describe("The command its checks run: its new test files and the existing ones that test what it changes"),
112
+ status: z
113
+ .enum(["new", "in-progress", "done", "dropped"])
114
+ .describe("new: written, not started. in-progress: its CL is being built. done: its CL landed. dropped: abandoned, kept for history"),
115
+ },
116
+ });
117
+ /** A plan's phases are its cls' `phase`, and they run 1, 2, 3 with no gap, so each cl has one. */
118
+ export const phases = defineRule({
119
+ name: "phases",
120
+ description: "A plan's cls each have a phase, and the phases run from 1 with no gap.",
121
+ on: plan,
122
+ check: (node, graph) => {
123
+ const cls = graph.all(cl).filter((c) => c.belongsTo === node.name);
124
+ const none = cls.filter((c) => c.phase === undefined).map((c) => c.name);
125
+ const have = new Set(cls.flatMap((c) => (c.phase === undefined ? [] : [c.phase])));
126
+ const missing = [...Array(Math.max(0, ...have)).keys()]
127
+ .map((i) => i + 1)
128
+ .filter((p) => !have.has(p));
129
+ return [
130
+ ...(none.length
131
+ ? [{ message: `its cls with no phase: ${none.join(", ")}` }]
132
+ : []),
133
+ ...(missing.length
134
+ ? [
135
+ {
136
+ message: `its phases have a gap: no cl in phase ${missing.join(", ")}`,
137
+ },
138
+ ]
139
+ : []),
140
+ ];
141
+ },
142
+ });
143
+ /** A plan is named for its issue: `<issue>-plan`. */
144
+ export const planName = defineRule({
145
+ name: "plan-name",
146
+ description: "A plan is named <issue>-plan, for the issue it belongs to.",
147
+ on: plan,
148
+ check: (node) => node.name === `${node.belongsTo}-plan`
149
+ ? []
150
+ : [
151
+ {
152
+ message: `a plan of ${node.belongsTo} is named ${node.belongsTo}-plan`,
153
+ },
154
+ ],
155
+ });
156
+ /** A cl is named for its issue and its cut: `<issue>-<cut>`, whether it belongs to the issue's plan or to the issue. */
157
+ export const clName = defineRule({
158
+ name: "cl-name",
159
+ description: "A cl is named <issue>-<cut>, for the issue it belongs to through its plan, or directly.",
160
+ on: cl,
161
+ check: (node, graph) => {
162
+ const issueName = graph.get(node.belongsTo, plan)?.belongsTo ?? node.belongsTo;
163
+ return node.name.startsWith(`${issueName}-`) &&
164
+ node.name !== `${issueName}-plan`
165
+ ? []
166
+ : [{ message: `a cl of ${issueName} is named ${issueName}-<cut>` }];
167
+ },
168
+ });
169
+ // Named, then exported: tsc does not rewrite the `.ts` of an import() inside `export default`'s expression, so the
170
+ // built package would import a file it does not ship.
171
+ const schema = defineSchema({
172
+ name: "work",
173
+ description: "The work: what is tracked, how it nests, and what blocks it.",
174
+ types: { work, objective, issue, plan, cl },
175
+ rules: [phases, planName, clName],
176
+ typeNotes: new URL("../types/", import.meta.url),
177
+ exports: () => import("./schema.js"),
178
+ });
179
+ export default schema;
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@mku1tra/work",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "The types of the work, on basis: objective, issue, plan and cl, each with a type note that says what each part of its notes holds.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/matta-kelly/assembly.git",
9
+ "directory": "work"
10
+ },
11
+ "type": "module",
12
+ "engines": {
13
+ "node": ">=22.18"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/schema.d.ts",
18
+ "default": "./dist/schema.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "types",
24
+ "!types/basis.config.ts"
25
+ ],
26
+ "scripts": {
27
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
28
+ "prepack": "npm run build"
29
+ },
30
+ "peerDependencies": {
31
+ "@mku1tra/basis": "^0.30.0",
32
+ "zod": "^4.6.0"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }
package/types/cl.md ADDED
@@ -0,0 +1,32 @@
1
+ ---
2
+ type: type
3
+ ---
4
+ The cut's intent, in one line: one sentence of done, said as what is true after its CL lands.
5
+
6
+ ---
7
+ ## Check
8
+
9
+ What it ensures: its promises, each one a future test ([[changelist#Behavior]]). Each promise can fail: a promise nothing could break is no check.
10
+
11
+ - behavior: given, when, then. It fails before the change and passes after
12
+ - structure: what stays green before and after, by its test files. When the tests themselves are what changes, the code stays as it is, and the mutation score holds
13
+ - a seam it creates: a promise that the seam holds, at its surface
14
+ - a Done item it completes: that item's test, which this cl writes red first ([[kinetic#Policy]], the promise rule)
15
+ - the whole behavior: a cut that asks an outside thing, waits, or says why it did a thing has a promise for each ([[code#Running]]). A promise left out is built by nobody, so the review finds it after the code
16
+ - the failed ask: what happens when the outside thing fails, or does not answer
17
+ - the limit: how long a wait may last, and what passing it does
18
+ - the record: where a reason or a result is kept, and who reads it there
19
+
20
+ ## Seam
21
+
22
+ What it keeps: the decision the cut hides from the other cls, what it must not change, and what crosses to them: the names, types and shapes the other side reads.
23
+
24
+ ## Checkout
25
+
26
+ The cl's context on disk: its `checkout` is the paths its builders get, as a git sparse checkout, so they start from what the planner already found and spend no turns finding it. It fences exploration, not edits.
27
+
28
+ - the paths: every file or folder conceivably relevant to the cut. Err wide: an extra path costs tokens, a missing one costs a raise
29
+ - each path: one line, what it is and why it is here: "`orchestrator/ledger.ts`: the ledger, where an attempt's record is kept"
30
+ - the exemplar: one file in the checkout its builders should write like, since a model of good code in the repo carries further than any rule
31
+ - a fact from outside the code: a probe's output or a doc, written here with its source
32
+ - a gap: a raise, not a search. A builder that needs a path the checkout does not hold raises it and stops, and the planner widens the checkout
package/types/issue.md ADDED
@@ -0,0 +1,29 @@
1
+ ---
2
+ type: type
3
+ ---
4
+ What this issue gets done, in one line: one sentence of done, said as what is true after.
5
+
6
+ ---
7
+ ## Intent
8
+
9
+ The work, shaped: the problem it answers and the rough form of the answer, solved enough to see whole and bounded enough to know where it stops (shaping: Singer, *Shape Up*, 2019). The main elements and how they connect, never the details, which are the plan's.
10
+
11
+ What validation (was it the right thing) is judged against. Every plan, CL and result is validated against it, and where one disagrees, the intent wins. It is never criteria: no list of done captures a need in full, and the gap is why the intent wins, and why a person validates.
12
+
13
+ ## Done
14
+
15
+ The state that meets the intent: what verification (was it built right) is judged against. The top of the V for one piece of work: a [[plan]] refines it into cls, every CL points to it by name ("Updates <name>" for a step, "Fixes <name>" on the last), and acceptance checks it on the way up ([Google Issue Tracker](https://developers.google.com/issue-tracker/concepts/issues)).
16
+
17
+ - a state, not an activity: "X is true", never "do X"
18
+ - it can fail: a claim nothing could falsify is no check
19
+ - it says where it is checked, set by where the claim lives and how long it must hold
20
+ - in the code, from then on: the acceptance test, on main. CI keeps it from then on
21
+ - one CL: that CL's tests, in its cl note
22
+ - more than one CL: each item's test, carried by the cl that completes it ([[kinetic#Policy]], the promise rule). The [[plan]] names that cl
23
+ - in the running system, once: proven where it runs, read from the running system after deploy (a request, a query, a log line). Main proves the code, not the fleet. Skipped only for code that runs nowhere
24
+ - in the running system, from then on: kept, by a monitor that keeps checking it, and where it alerts. Only when the claim can break again after met
25
+ - the test of a good list: someone who did not write it can check every item without asking
26
+
27
+ ## Non-goals
28
+
29
+ What this issue will not do, said plainly. The fence for review: work past it is scope the issue did not ask for, and a shrink inside it is a raise, never quiet.
@@ -0,0 +1,17 @@
1
+ ---
2
+ type: type
3
+ ---
4
+ The end state, in one line.
5
+
6
+ An objective and its key results: where to go, and how to tell you are getting there ([re:Work](https://rework.withgoogle.com/intl/en/guides/set-goals-with-okrs)). Fill it in over this guide.
7
+
8
+ - objective: an end state, obvious to an outsider whether it was met. "ship feature Y", not "keep doing X"
9
+ - key results: about 3, each measurable, each an outcome, not an activity
10
+ - one active at a time
11
+ - status: draft, active, archived, dropped
12
+ - issues hang under it by `belongsTo`
13
+ - not a to-do list
14
+
15
+ ---
16
+ ## Key results
17
+ -
package/types/plan.md ADDED
@@ -0,0 +1,25 @@
1
+ ---
2
+ type: type
3
+ ---
4
+ The approach, in one or two sentences: how the cls, in order, meet the issue's Done. A known way to cut a kind of change gives a ready order ([[playbook#Cutting a change]]); when none fits, build one, and say so.
5
+
6
+ ---
7
+ ## Phases
8
+
9
+ The refinement of the issue: the cls replace its Done with smaller specs, and the phases show how they combine, so that meeting all of them meets the issue (stepwise refinement: Wirth, 1971; Lamport, *A Science of Concurrent Programs*, ch. 6). Dependent CLs are split and ordered "at a high level before diving into coding" ([Small CLs](https://google.github.io/eng-practices/review/developer/small-cls.html)), because "a bad line of a plan could lead to hundreds of bad lines of code" ([HumanLayer](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md)).
10
+ - a phase: a group of cls that need nothing from each other, so they can be built side by side: no two change the same code, and none requires another's ensures. Two cls that must change the same code go in different phases, and each phase's reason says why its cls stay apart. Order is only between phases: a phase starts once every cl of the phases before it has landed (a partial order: Lamport, 1978). Inside a phase, cls are parallel, or a set (the same change in many places: SWE at Google, ch. 22). Each cl holds its `phase`, and this list names the same cls in the same phases
11
+ - a hard line: where a cut must fall, whatever the design. A cl lands in one repo, through one review, and ships alone, so a part in another repo, for another reviewer or deployed apart is its own cut. Work that is not code (access, accounts, shares) is no cut: it is a step done by hand, checked by a read
12
+ - a cut: the cls meet at seams, each an interface between cuts: what one side promises the other, and what neither touches. Cut along decisions hidden behind an interface, not along the steps of a flow ([Parnas, 1972](https://dl.acm.org/doi/10.1145/361598.361623))
13
+ - a cl ([[cl]]): a contract: what it ensures, requires and must keep. It has its own intent and a check that can fail, fits one review, and leaves main working once it lands ([[changelist#Good CL]]). If you can't write a cut's check, the cut is wrong
14
+ - the proof: every Done item is met by a cl, and every cl meets one. A cl that meets nothing is scope the issue did not ask for. A seam's promise is in the Check of the cl that creates the seam, and each Done item's test in the Check of the cl that completes it ([[kinetic#Policy]], the promise rule)
15
+ - every claim stands on shown ground: the code or a probe's output, never a summary of them
16
+ - the list: a line for each phase, what it builds and why it comes where it does, and under it a line for each of its cls, what it hides and what crosses to the others
17
+
18
+ - Phase 1: what it builds, and why it comes first
19
+ - [[<issue>-<cut>]]: what it hides, and what crosses to the others
20
+ - Phase 2: what it builds, and what it needs from phase 1
21
+ - [[<issue>-<cut>]]: what it hides, and what crosses to the others
22
+
23
+ ## Does not fit
24
+
25
+ What could not be made to fit, said plainly: a seam it could not prove, a cut it could not check, a Done item no cl meets. Removed when everything fits. plan-review judges the plan against the issue's Intent and Done before any cl starts, and reads this first, because it is where forcing shows up. The plan is done when its issue is met, not when its last cl lands.
package/types/work.md ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ type: type
3
+ ---
4
+
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.