@okfit/profiles 0.5.0 → 0.7.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 CHANGED
@@ -6,20 +6,23 @@ Named configuration profiles for [okfit](https://github.com/spencerbeggs/okfit).
6
6
 
7
7
  ## The `software-project` profile
8
8
 
9
- `Profiles.softwareProject.config` is a hand-authored `OkfitConfig` (P-25) that sets only `concepts`, `types`, `tags`, and `extensions: {}`; `okf_version`, `bundle`, `lifecycle`, `actors`, and `lint` are inherited from `OkfitConfig.DEFAULTS` by whoever merges it (the CLI applies `DEFAULTS < profile < file` with `OkfitConfig.merge`). `Profiles.get(name)` resolves a profile by its exact name and answers `Option.none` for `"none"` and unknown names. The TOML below decodes to the exact same value and is checked against the literal by `__test__/SoftwareProject.test.ts`:
9
+ `Profiles.softwareProject.config` is a hand-authored `OkfitConfig` (P-25) that sets only `concepts`, `types`, `tags`, `extensions: {}`, and one `lint` opinion (`status_missing = "warn"`, so a concept with neither `status` nor `verified` is reported instead of silently reading as stable); `okf_version`, `bundle`, `lifecycle`, `actors`, and every other `lint` severity are inherited from `OkfitConfig.DEFAULTS` by whoever merges it (the CLI applies `DEFAULTS < profile < file` with `OkfitConfig.merge`). `Profiles.get(name)` resolves a profile by its exact name and answers `Option.none` for `"none"` and unknown names. The TOML below decodes to the exact same value and is checked against the literal by `__test__/SoftwareProject.test.ts`:
10
10
 
11
11
  ```toml
12
12
  [concepts]
13
13
  required = ["title", "description"]
14
14
  tags.required = []
15
15
 
16
+ [lint]
17
+ status_missing = "warn"
18
+
16
19
  [types.Project]
17
20
  description = "The repository's root concept: its purpose, boundaries, and non-goals."
18
21
  guidance = "Exactly one Project exists and it lives at the bundle root as the project file. State the purpose in one paragraph and list what is deliberately out of scope so a reader never infers boundaries from silence."
19
22
 
20
23
  [types.Module]
21
24
  description = "A unit of code with an owner and a boundary."
22
- guidance = "One per workspace package, plugin, website, action, test harness, or config dependency. Link to the Decisions that shaped it and the Conventions it is bound by."
25
+ guidance = "One per workspace package, plugin, website, action, worker, test harness, or config dependency. Link to the Decisions that shaped it and the Conventions it is bound by."
23
26
  required = ["resource", "kind"]
24
27
 
25
28
  [types.Module.fields.kind]
@@ -29,6 +32,7 @@ values.package = "A publishable npm package under packages/."
29
32
  values.website = "A docs or marketing site, usually RSPress."
30
33
  values.plugin = "A Claude Code or editor plugin distributed outside npm."
31
34
  values.action = "A GitHub Action."
35
+ values.worker = "A detached runtime unit, such as a sidecar or worker bundle, spawned by another module with its own lifecycle and not itself a package or action."
32
36
  values.harness = "A private test-only package or package group that exercises built artifacts and is never published."
33
37
  values.config-dependency = "A package consumed through pnpm configDependencies rather than dependencies, loaded before the workspace resolves."
34
38
 
@@ -110,7 +114,7 @@ kind = "path"
110
114
 
111
115
  [types.Gotcha]
112
116
  description = "A state or result that looks like one thing and is the opposite: breakage that is transient, or success that did nothing."
113
- guidance = "Describe what a reader sees, what they will wrongly conclude, and what is actually true, and point resource at the code or command that produces the misleading signal. Give it a staleness window, since a trap fixed upstream turns into misinformation."
117
+ guidance = "Describe what a reader sees, what they will wrongly conclude, and what is actually true, and point resource at the code or command that produces the misleading signal, or omit resource and name the outside system when nothing in this repository produces it. Give it a staleness window, since a trap fixed upstream turns into misinformation; a known bug nobody is scheduled to fix is a Gotcha, and becomes a Roadmap once the fix is planned."
114
118
 
115
119
  [types.Gotcha.fields.resource]
116
120
  description = "A path relative to this concept file to the code, script, or config that produces the misleading signal."
@@ -126,7 +130,7 @@ description = "Where the consumer lives, as a URL or an owner/name pair, since i
126
130
 
127
131
  [types.Roadmap]
128
132
  description = "A gate and the forward-looking work behind it, held as intent rather than as a Decision."
129
- guidance = "List the phases and what remains in each, and give it a staleness window so queued work is re-examined instead of read as settled. Deprecate it when the gate holds and write the Decisions the work produced."
133
+ guidance = "List the phases and what remains in each, and give it a staleness window so queued work is re-examined instead of read as settled. Deprecate it when the gate holds and write the Decisions the work produced; a known bug with nobody queued to fix it is a Gotcha, not a Roadmap."
130
134
 
131
135
  [types.Roadmap.fields.gate]
132
136
  description = "The observable condition that closes this roadmap, for example a release shipped or a benchmark met."
@@ -139,6 +143,26 @@ guidance = "Record the inputs, the method, and the numbers so a reader can judge
139
143
  description = "Paths to the Decisions this measurement supports, one entry per Decision."
140
144
  kind = "path"
141
145
 
146
+ [types.Invariant]
147
+ description = "A property the code holds by construction: enforced by the type system or pinned by a test, not followed by people."
148
+ guidance = "State the property, name the mechanism that enforces it, and say what a refactor would have to break for it to stop holding. Distinct from Convention, which a contributor can choose to ignore."
149
+
150
+ [types.Invariant.fields.resource]
151
+ description = "A path relative to this concept file to the type, function, or test that enforces the property."
152
+ kind = "path"
153
+
154
+ [types.Incident]
155
+ description = "A dated production failure: what shipped broken, what it looked like to the consumer, the root cause, and the guard that now stops it."
156
+ guidance = "Keep the whole narrative in one record rather than splitting the misleading signal into a Gotcha and the guard into a Decision, and link both where they exist. Set occurred to the date it happened so a reader can weigh how far the code has moved since."
157
+ required = ["occurred"]
158
+
159
+ [types.Incident.fields.occurred]
160
+ description = "The ISO 8601 date the failure happened or was first observed."
161
+
162
+ [types.Incident.fields.guard]
163
+ description = "A path relative to this concept file to the test, check, or config that now stops the failure recurring."
164
+ kind = "path"
165
+
142
166
  [tags.architecture]
143
167
  description = "Concerns the shape of the system rather than one module."
144
168
 
@@ -171,6 +195,12 @@ description = "Concerns how the system reports on itself: events, metrics, logs,
171
195
 
172
196
  [tags.deps]
173
197
  description = "Concerns how third-party dependencies are declared, pinned, and distributed."
198
+
199
+ [tags.github]
200
+ description = "Concerns the GitHub platform surface: the REST and GraphQL APIs, Apps and installation tokens, Actions, Packages, check runs, and pull request conventions."
201
+
202
+ [tags.docs]
203
+ description = "Concerns the documentation itself: provenance, rot, re-derivation, and what a claim would take to falsify."
174
204
  ```
175
205
 
176
206
  Only `concepts`, `types`, and `tags` carry real vocabulary; the literal's `extensions: {}` is `OkfitConfig`'s one required key and never appears on disk, since the codec folds unknown top-level keys into it (P-24: `fields.<k>.kind = "path"` and the `tags` table are vocabulary only — core enforces none of it yet). `Reference.required = ["sources"]` checks presence only: `sources = []` passes, and each entry's shape is core's `family-invalid` (P-23).
@@ -1,8 +1,11 @@
1
1
  //#region src/SoftwareProject.ts
2
2
  /**
3
3
  * Hand-authored, typed `OkfitConfig` (P-25). Sets ONLY `concepts`, `types`,
4
- * `tags` and `extensions: {}`; `okf_version`, `bundle`, `lifecycle`, `actors`
5
- * and `lint` are inherited from `OkfitConfig.DEFAULTS` by whoever merges.
4
+ * `tags`, `extensions: {}` and one `lint` opinion (`status_missing = "warn"`,
5
+ * issue #110: a software project wants every concept's status written down
6
+ * rather than read from silence); `okf_version`, `bundle`, `lifecycle`,
7
+ * `actors` and the rest of `lint` are inherited from `OkfitConfig.DEFAULTS`
8
+ * by whoever merges.
6
9
  * `actors.agent` is deliberately unset (P-17): which agent writes is a fact
7
10
  * about the repository, not about the software-project shape. Every string
8
11
  * obeys P-42 (one-sentence descriptions, at most two-sentence guidance, plain
@@ -15,6 +18,7 @@ const config = {
15
18
  required: ["title", "description"],
16
19
  tags: { required: [] }
17
20
  },
21
+ lint: { status_missing: "warn" },
18
22
  types: {
19
23
  Project: {
20
24
  description: "The repository's root concept: its purpose, boundaries, and non-goals.",
@@ -22,7 +26,7 @@ const config = {
22
26
  },
23
27
  Module: {
24
28
  description: "A unit of code with an owner and a boundary.",
25
- guidance: "One per workspace package, plugin, website, action, test harness, or config dependency. Link to the Decisions that shaped it and the Conventions it is bound by.",
29
+ guidance: "One per workspace package, plugin, website, action, worker, test harness, or config dependency. Link to the Decisions that shaped it and the Conventions it is bound by.",
26
30
  required: ["resource", "kind"],
27
31
  fields: {
28
32
  kind: {
@@ -33,6 +37,7 @@ const config = {
33
37
  website: "A docs or marketing site, usually RSPress.",
34
38
  plugin: "A Claude Code or editor plugin distributed outside npm.",
35
39
  action: "A GitHub Action.",
40
+ worker: "A detached runtime unit, such as a sidecar or worker bundle, spawned by another module with its own lifecycle and not itself a package or action.",
36
41
  harness: "A private test-only package or package group that exercises built artifacts and is never published.",
37
42
  "config-dependency": "A package consumed through pnpm configDependencies rather than dependencies, loaded before the workspace resolves."
38
43
  }
@@ -119,7 +124,7 @@ const config = {
119
124
  },
120
125
  Gotcha: {
121
126
  description: "A state or result that looks like one thing and is the opposite: breakage that is transient, or success that did nothing.",
122
- guidance: "Describe what a reader sees, what they will wrongly conclude, and what is actually true, and point resource at the code or command that produces the misleading signal. Give it a staleness window, since a trap fixed upstream turns into misinformation.",
127
+ guidance: "Describe what a reader sees, what they will wrongly conclude, and what is actually true, and point resource at the code or command that produces the misleading signal, or omit resource and name the outside system when nothing in this repository produces it. Give it a staleness window, since a trap fixed upstream turns into misinformation; a known bug nobody is scheduled to fix is a Gotcha, and becomes a Roadmap once the fix is planned.",
123
128
  fields: { resource: {
124
129
  description: "A path relative to this concept file to the code, script, or config that produces the misleading signal.",
125
130
  kind: "path"
@@ -133,7 +138,7 @@ const config = {
133
138
  },
134
139
  Roadmap: {
135
140
  description: "A gate and the forward-looking work behind it, held as intent rather than as a Decision.",
136
- guidance: "List the phases and what remains in each, and give it a staleness window so queued work is re-examined instead of read as settled. Deprecate it when the gate holds and write the Decisions the work produced.",
141
+ guidance: "List the phases and what remains in each, and give it a staleness window so queued work is re-examined instead of read as settled. Deprecate it when the gate holds and write the Decisions the work produced; a known bug with nobody queued to fix it is a Gotcha, not a Roadmap.",
137
142
  fields: { gate: { description: "The observable condition that closes this roadmap, for example a release shipped or a benchmark met." } }
138
143
  },
139
144
  Measurement: {
@@ -143,6 +148,26 @@ const config = {
143
148
  description: "Paths to the Decisions this measurement supports, one entry per Decision.",
144
149
  kind: "path"
145
150
  } }
151
+ },
152
+ Invariant: {
153
+ description: "A property the code holds by construction: enforced by the type system or pinned by a test, not followed by people.",
154
+ guidance: "State the property, name the mechanism that enforces it, and say what a refactor would have to break for it to stop holding. Distinct from Convention, which a contributor can choose to ignore.",
155
+ fields: { resource: {
156
+ description: "A path relative to this concept file to the type, function, or test that enforces the property.",
157
+ kind: "path"
158
+ } }
159
+ },
160
+ Incident: {
161
+ description: "A dated production failure: what shipped broken, what it looked like to the consumer, the root cause, and the guard that now stops it.",
162
+ guidance: "Keep the whole narrative in one record rather than splitting the misleading signal into a Gotcha and the guard into a Decision, and link both where they exist. Set occurred to the date it happened so a reader can weigh how far the code has moved since.",
163
+ required: ["occurred"],
164
+ fields: {
165
+ occurred: { description: "The ISO 8601 date the failure happened or was first observed." },
166
+ guard: {
167
+ description: "A path relative to this concept file to the test, check, or config that now stops the failure recurring.",
168
+ kind: "path"
169
+ }
170
+ }
146
171
  }
147
172
  },
148
173
  tags: {
@@ -156,7 +181,9 @@ const config = {
156
181
  compat: { description: "Concerns compatibility across versions of the runtime, the package manager, or a dependency." },
157
182
  bundle: { description: "Concerns install weight and reachability: tree-shaking, subpath entrypoints, and dependency edges declined for their cost." },
158
183
  observability: { description: "Concerns how the system reports on itself: events, metrics, logs, sinks, and artifacts." },
159
- deps: { description: "Concerns how third-party dependencies are declared, pinned, and distributed." }
184
+ deps: { description: "Concerns how third-party dependencies are declared, pinned, and distributed." },
185
+ github: { description: "Concerns the GitHub platform surface: the REST and GraphQL APIs, Apps and installation tokens, Actions, Packages, check runs, and pull request conventions." },
186
+ docs: { description: "Concerns the documentation itself: provenance, rot, re-derivation, and what a claim would take to falsify." }
160
187
  },
161
188
  extensions: {}
162
189
  };
@@ -219,6 +246,14 @@ const layout = {
219
246
  {
220
247
  directory: "measurements",
221
248
  type: "Measurement"
249
+ },
250
+ {
251
+ directory: "invariants",
252
+ type: "Invariant"
253
+ },
254
+ {
255
+ directory: "incidents",
256
+ type: "Incident"
222
257
  }
223
258
  ]
224
259
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okfit/profiles",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "Named OKF configuration profiles for okfit, starting with the software-project profile.",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "peerDependencies": {
38
38
  "@effected/git": "^0.15.0",
39
39
  "@effected/markdown": "^0.10.0",
40
- "@okfit/core": "^0.4.1",
40
+ "@okfit/core": "^0.5.0",
41
41
  "effect": "4.0.0-rc.115"
42
42
  },
43
43
  "engines": {