@okfit/engine 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/errors.js CHANGED
@@ -104,6 +104,40 @@ var ConfigMalformedError = class extends Schema.TaggedError()("ConfigMalformedEr
104
104
  return `malformed config ${this.path}: ${messageOf(this.cause)}`;
105
105
  }
106
106
  };
107
+ /**
108
+ * Issue #140: `sync --staged` stamps the git index with a caller-given
109
+ * instant instead of walking history, but a log group's date must come
110
+ * from a commit, never from that stamp time -- so `runSync` refuses to
111
+ * combine `staged` with log mode rather than write a fabricated date.
112
+ *
113
+ * @public
114
+ */
115
+ var SyncStagedLogError = class extends Schema.TaggedError()("SyncStagedLogError", {}) {
116
+ [Runtime.errorExitCode] = 64;
117
+ get message() {
118
+ return "--staged cannot run log mode: a log group's date must come from a commit, not from the stamp time; use --only generated and/or --only index";
119
+ }
120
+ };
121
+ /**
122
+ * Issue #138: `okfit verify`'s selection was contradictory or empty. Exit 64: a usage error.
123
+ *
124
+ * @public
125
+ */
126
+ var VerifySelectionError = class extends Schema.TaggedError()("VerifySelectionError", {
127
+ reason: Schema.Literals([
128
+ "no-selection",
129
+ "id-and-batch",
130
+ "unknown-type"
131
+ ]),
132
+ detail: Schema.optionalKey(Schema.String)
133
+ }) {
134
+ [Runtime.errorExitCode] = 64;
135
+ get message() {
136
+ if (this.reason === "no-selection") return "verify needs a concept id, --all, or --type <Type>";
137
+ if (this.reason === "id-and-batch") return "verify takes either a concept id or --all/--type, not both";
138
+ return `type "${this.detail ?? ""}" is not declared in the config`;
139
+ }
140
+ };
107
141
 
108
142
  //#endregion
109
- export { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, VerifyConceptNotFoundError, VerifyUnsupportedFrontmatterError };
143
+ export { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, SyncStagedLogError, VerifyConceptNotFoundError, VerifySelectionError, VerifyUnsupportedFrontmatterError };
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BundleLoadError, ConceptId, Diagnostic, DiagnosticRange, DiagnosticSeverity, GraphLink, GraphNode, LinkGraph, LoadedBundle, OkfitConfig, OkfitConfigFile, StaleConcept, ValidationReport } from "@okfit/core";
1
+ import { Actor, BundleLoadError, ConceptId, Diagnostic, DiagnosticRange, DiagnosticSeverity, GraphLink, GraphNode, LinkGraph, LoadedBundle, OkfitConfig, OkfitConfigFile, StaleConcept, ValidationReport } from "@okfit/core";
2
2
  import { Context, Crypto, DateTime, Effect, FileSystem, Layer, Option, Path, PlatformError, Runtime, Schema } from "effect";
3
3
  import { AppDirs, Xdg } from "@effected/xdg";
4
4
  import { ConfigReadError } from "@effected/config-file";
@@ -156,6 +156,32 @@ export declare class ConfigMalformedError extends ConfigMalformedError_base {
156
156
  readonly [Runtime.errorExitCode] = 3;
157
157
  get message(): string;
158
158
  }
159
+ declare const SyncStagedLogError_base: Schema.Class<SyncStagedLogError, Schema.TaggedStruct<"SyncStagedLogError", {}>, import("effect/Cause").YieldableError>;
160
+ /**
161
+ * Issue #140: `sync --staged` stamps the git index with a caller-given
162
+ * instant instead of walking history, but a log group's date must come
163
+ * from a commit, never from that stamp time -- so `runSync` refuses to
164
+ * combine `staged` with log mode rather than write a fabricated date.
165
+ *
166
+ * @public
167
+ */
168
+ export declare class SyncStagedLogError extends SyncStagedLogError_base {
169
+ readonly [Runtime.errorExitCode] = 64;
170
+ get message(): string;
171
+ }
172
+ declare const VerifySelectionError_base: Schema.Class<VerifySelectionError, Schema.TaggedStruct<"VerifySelectionError", {
173
+ readonly reason: Schema.Literals<readonly ["no-selection", "id-and-batch", "unknown-type"]>;
174
+ readonly detail: Schema.optionalKey<Schema.String>;
175
+ }>, import("effect/Cause").YieldableError>;
176
+ /**
177
+ * Issue #138: `okfit verify`'s selection was contradictory or empty. Exit 64: a usage error.
178
+ *
179
+ * @public
180
+ */
181
+ export declare class VerifySelectionError extends VerifySelectionError_base {
182
+ readonly [Runtime.errorExitCode] = 64;
183
+ get message(): string;
184
+ }
159
185
  //#endregion
160
186
  //#region src/config/layer.d.ts
161
187
  /**
@@ -353,8 +379,6 @@ export declare const runGraph: (options: GraphRunOptions) => Effect.Effect<Graph
353
379
  //#region src/init/scaffold.d.ts
354
380
  /** `.config/okfit.toml`, relative to the project root (C-10). @public */
355
381
  export declare const CONFIG_RELATIVE_PATH = ".config/okfit.toml";
356
- /** C-22's directive, plus the blank line Tombi requires. @public */
357
- export declare const SCHEMA_DIRECTIVE = "#:schema https://raw.githubusercontent.com/spencerbeggs/okfit/main/schemas/config/okfit-1.0.0.json\n\n";
358
382
  /** @public */
359
383
  interface ScaffoldOptions {
360
384
  /** Absolute. */
@@ -519,10 +543,15 @@ export type ContextTag = typeof ContextTag.Type;
519
543
  * consumer can tell "no profile configured" apart from "an unknown profile
520
544
  * was configured".
521
545
  *
546
+ * `config_schema_version` is `@okfit/core`'s `CONFIG_SCHEMA_VERSION`,
547
+ * stamped by {@link contextEnvelope} itself -- callers cannot pass or fake
548
+ * it (okfit #137).
549
+ *
522
550
  * @public
523
551
  */
524
552
  export declare const ContextEnvelope: Schema.Struct<{
525
553
  readonly schema: Schema.Literal<1>;
554
+ readonly config_schema_version: Schema.String;
526
555
  readonly project_root: Schema.String;
527
556
  readonly bundle_root: Schema.String;
528
557
  readonly config_path: Schema.NullOr<Schema.String>;
@@ -575,6 +604,29 @@ export declare const contextEnvelope: (input: {
575
604
  readonly config: OkfitConfig;
576
605
  }) => ContextEnvelope;
577
606
  //#endregion
607
+ //#region src/render/distribution.d.ts
608
+ /**
609
+ * The meta-package an okfit report's bins were installed through -- e.g.
610
+ * `@okfit/plugin` -- threaded into `main(options)` by that package's bin
611
+ * shims (okfit #137). `null` for a direct install of `@okfit/cli` or
612
+ * `@okfit/mcp`. This is packaging metadata, not a number to compare across
613
+ * reports; `engine_version` and `okf_version` are the pair a reader
614
+ * compares.
615
+ *
616
+ * @public
617
+ */
618
+ interface Distribution {
619
+ readonly name: string;
620
+ readonly version: string;
621
+ }
622
+ /** Every envelope's `distribution` field: a `Distribution` or `null`. @public */
623
+ export declare const DistributionField: Schema.NullOr<Schema.Struct<{
624
+ readonly name: Schema.String;
625
+ readonly version: Schema.String;
626
+ }>>;
627
+ /** @public */
628
+ export type DistributionField = typeof DistributionField.Type;
629
+ //#endregion
578
630
  //#region src/render/sort.d.ts
579
631
  /** Which producer a diagnostic came from; the JSON envelope's `source` (K-21). @public */
580
632
  type DiagnosticSource = "core.conformance" | "core.lint" | "profile";
@@ -680,7 +732,12 @@ export type GraphSummary = typeof GraphSummary.Type;
680
732
  export declare const GraphEnvelope: Schema.Struct<{
681
733
  readonly schema: Schema.Literal<1>;
682
734
  readonly okfit_version: Schema.String;
735
+ readonly engine_version: Schema.String;
683
736
  readonly producer: Schema.String;
737
+ readonly distribution: Schema.NullOr<Schema.Struct<{
738
+ readonly name: Schema.String;
739
+ readonly version: Schema.String;
740
+ }>>;
684
741
  readonly okf_version: Schema.String;
685
742
  readonly root: Schema.String;
686
743
  readonly profile: Schema.NullOr<Schema.String>;
@@ -716,6 +773,7 @@ export declare const graphEnvelope: (input: {
716
773
  readonly profile: string | null;
717
774
  readonly nodes: ReadonlyArray<GraphNode>;
718
775
  readonly edges: ReadonlyArray<GraphLink>;
776
+ readonly distribution?: Distribution;
719
777
  }) => GraphEnvelope;
720
778
  //#endregion
721
779
  //#region src/render/json.d.ts
@@ -744,18 +802,26 @@ export type JsonSummary = typeof JsonSummary.Type;
744
802
  /**
745
803
  * K-21's success envelope, snake_case. `exit_code` is `0 | 1 | 2` only: an
746
804
  * infrastructure failure never produces this envelope, it produces the
747
- * `JsonErrorEnvelope` (K-22). `okfit_version` names the version of the
748
- * package that produced the report (J-2), so the CLI and the MCP server
749
- * legitimately report different numbers over one bundle; `producer` names
750
- * that package (`okfit` or `@okfit/mcp`) so the difference reads as two
751
- * producers, not as drift (okfit #75).
805
+ * `JsonErrorEnvelope` (K-22). `okfit_version` and `producer` identify the
806
+ * PACKAGE that produced the report (J-2), so the CLI and the MCP server
807
+ * legitimately report different numbers over one bundle without that
808
+ * reading as drift (okfit #75); `engine_version` and `okf_version` are the
809
+ * pair that determines the report's content and the pair a reader should
810
+ * actually compare across two producers. `distribution` names the
811
+ * meta-package the bins were installed through (`@okfit/plugin`), or `null`
812
+ * for a direct install of `@okfit/cli`/`@okfit/mcp` (okfit #137).
752
813
  *
753
814
  * @public
754
815
  */
755
816
  export declare const JsonEnvelope: Schema.Struct<{
756
817
  readonly schema: Schema.Literal<1>;
757
818
  readonly okfit_version: Schema.String;
819
+ readonly engine_version: Schema.String;
758
820
  readonly producer: Schema.String;
821
+ readonly distribution: Schema.NullOr<Schema.Struct<{
822
+ readonly name: Schema.String;
823
+ readonly version: Schema.String;
824
+ }>>;
759
825
  readonly okf_version: Schema.String;
760
826
  readonly root: Schema.String;
761
827
  readonly profile: Schema.NullOr<Schema.String>;
@@ -779,11 +845,23 @@ export declare const JsonEnvelope: Schema.Struct<{
779
845
  }>;
780
846
  /** @public */
781
847
  export type JsonEnvelope = typeof JsonEnvelope.Type;
782
- /** K-22's envelope: the ONLY thing stdout carries under `--format json` on an exit-3 failure. @public */
848
+ /**
849
+ * K-22's envelope: the ONLY thing stdout carries under `--format json` on an
850
+ * infrastructure failure. `exit_code` is `3` for most errors, or `64` for the
851
+ * usage-tier errors (`SyncStagedLogError`, `VerifySelectionError`) that carry
852
+ * their own `[Runtime.errorExitCode]`.
853
+ *
854
+ * @public
855
+ */
783
856
  export declare const JsonErrorEnvelope: Schema.Struct<{
784
857
  readonly schema: Schema.Literal<1>;
785
858
  readonly okfit_version: Schema.String;
786
- readonly exit_code: Schema.Literal<3>;
859
+ readonly engine_version: Schema.String;
860
+ readonly distribution: Schema.NullOr<Schema.Struct<{
861
+ readonly name: Schema.String;
862
+ readonly version: Schema.String;
863
+ }>>;
864
+ readonly exit_code: Schema.Literals<readonly [3, 64]>;
787
865
  readonly error: Schema.Struct<{
788
866
  readonly tag: Schema.String;
789
867
  readonly message: Schema.String;
@@ -811,9 +889,10 @@ export declare const json: (input: {
811
889
  readonly exitCode: 0 | 1 | 2;
812
890
  readonly concepts: number;
813
891
  readonly diagnostics: ReadonlyArray<RenderedDiagnostic>;
892
+ readonly distribution?: Distribution;
814
893
  }) => JsonEnvelope;
815
894
  /** K-22. `tag` is the error's `_tag` when it has one, else its constructor name. @public */
816
- export declare const jsonError: (error: unknown, okfitVersion: string) => JsonErrorEnvelope;
895
+ export declare const jsonError: (error: unknown, okfitVersion: string, distribution?: Distribution) => JsonErrorEnvelope;
817
896
  //#endregion
818
897
  //#region src/render/stale.d.ts
819
898
  /** One entry of the `items` array. @public */
@@ -843,7 +922,12 @@ export type StaleSummary = typeof StaleSummary.Type;
843
922
  export declare const StaleEnvelope: Schema.Struct<{
844
923
  readonly schema: Schema.Literal<1>;
845
924
  readonly okfit_version: Schema.String;
925
+ readonly engine_version: Schema.String;
846
926
  readonly producer: Schema.String;
927
+ readonly distribution: Schema.NullOr<Schema.Struct<{
928
+ readonly name: Schema.String;
929
+ readonly version: Schema.String;
930
+ }>>;
847
931
  readonly okf_version: Schema.String;
848
932
  readonly root: Schema.String;
849
933
  readonly profile: Schema.NullOr<Schema.String>;
@@ -876,6 +960,7 @@ export declare const staleEnvelope: (input: {
876
960
  readonly now: DateTime.Utc;
877
961
  readonly concepts: number;
878
962
  readonly items: ReadonlyArray<StaleConcept>;
963
+ readonly distribution?: Distribution;
879
964
  }) => StaleEnvelope;
880
965
  //#endregion
881
966
  //#region src/sync/run.d.ts
@@ -895,11 +980,17 @@ export type SkipReason = typeof SkipReason.Type;
895
980
  interface SyncOptions {
896
981
  /** Absolute bundle root, from `resolveProjectConfig`. */
897
982
  readonly bundleRoot: string;
898
- /** Already merged `DEFAULTS < profile < file` by the caller (D-28); unused today (`sync` never calls `profile.check`) but carried for parity with `RunOptions`. */
983
+ /** Already merged `DEFAULTS < profile < file` by the caller (D-28). `actors.agent`, when set, is threaded into `syncGenerated` (issue #73) so a concept with no `generated` block gets one created; `sync` never calls `profile.check`. */
899
984
  readonly config: OkfitConfig;
900
985
  /** Members to actually RUN. Absent members still appear in {@link SyncResult}, `selected: false`. */
901
986
  readonly modes: ReadonlySet<SyncMode>;
902
987
  readonly dryRun: boolean;
988
+ /** Issue #18: log mode's inclusive floor (`YYYY-MM-DD`); default is the newest logged date. */
989
+ readonly logSince?: string;
990
+ /** Issue #140: stamp the concepts in the git index with this instant instead of walking history; log mode must not be selected. */
991
+ readonly staged?: {
992
+ readonly at: DateTime.Utc;
993
+ };
903
994
  }
904
995
  /** @public */
905
996
  interface SyncModeResult {
@@ -921,16 +1012,17 @@ interface SyncResult {
921
1012
  readonly log: SyncModeResult;
922
1013
  }
923
1014
  /**
924
- * Contract §5's six-step algorithm: one `Bundle.load`, one
925
- * `Derivation.generatedAt` per concept shared by the generated and log
926
- * modes (skipped entirely when neither is selected), then the three modes
927
- * in a FIXED order — generated, index, log — regardless of `--only`'s own
928
- * occurrence order, so a generated write never invalidates an index or log
929
- * rendered in the same run (design §2).
1015
+ * Contract §5's six-step algorithm: one `Bundle.load`, then a lazy
1016
+ * `Derivation.generatedAt` walk shared by the generated and log modes
1017
+ * (issue #21) — computed only for a concept that still needs one, not for
1018
+ * every concept — then the three modes in a FIXED order — generated,
1019
+ * index, log — regardless of `--only`'s own occurrence order, so a
1020
+ * generated write never invalidates an index or log rendered in the same
1021
+ * run (design §2).
930
1022
  *
931
1023
  * @public
932
1024
  */
933
- export declare const runSync: (options: SyncOptions) => Effect.Effect<SyncResult, BundleLoadError | GeneratedAtError, Git | GitHistory | FileSystem.FileSystem | Path.Path | Crypto.Crypto>;
1025
+ export declare const runSync: (options: SyncOptions) => Effect.Effect<SyncResult, BundleLoadError | GeneratedAtError | SyncStagedLogError, Git | GitHistory | FileSystem.FileSystem | Path.Path | Crypto.Crypto>;
934
1026
  //#endregion
935
1027
  //#region src/render/sync.d.ts
936
1028
  /** @public */
@@ -959,6 +1051,11 @@ export type SyncModeEnvelope = typeof SyncModeEnvelope.Type;
959
1051
  export declare const SyncEnvelope: Schema.Struct<{
960
1052
  readonly schema: Schema.Literal<1>;
961
1053
  readonly okfit_version: Schema.String;
1054
+ readonly engine_version: Schema.String;
1055
+ readonly distribution: Schema.NullOr<Schema.Struct<{
1056
+ readonly name: Schema.String;
1057
+ readonly version: Schema.String;
1058
+ }>>;
962
1059
  readonly root: Schema.String;
963
1060
  readonly dry_run: Schema.Boolean;
964
1061
  readonly exit_code: Schema.Literal<0>;
@@ -1004,6 +1101,7 @@ export declare const syncEnvelope: (input: {
1004
1101
  readonly root: string;
1005
1102
  readonly dryRun: boolean;
1006
1103
  readonly result: SyncResult;
1104
+ readonly distribution?: Distribution;
1007
1105
  }) => SyncEnvelope;
1008
1106
  //#endregion
1009
1107
  //#region src/render/verify.d.ts
@@ -1019,6 +1117,11 @@ export declare const syncEnvelope: (input: {
1019
1117
  export declare const VerifyEnvelope: Schema.Struct<{
1020
1118
  readonly schema: Schema.Literal<1>;
1021
1119
  readonly okfit_version: Schema.String;
1120
+ readonly engine_version: Schema.String;
1121
+ readonly distribution: Schema.NullOr<Schema.Struct<{
1122
+ readonly name: Schema.String;
1123
+ readonly version: Schema.String;
1124
+ }>>;
1022
1125
  readonly id: Schema.String;
1023
1126
  readonly path: Schema.String;
1024
1127
  readonly verified: Schema.Struct<{
@@ -1045,7 +1148,60 @@ export declare const verifyEnvelope: (input: {
1045
1148
  readonly by: string;
1046
1149
  readonly at: string;
1047
1150
  readonly dryRun: boolean;
1151
+ readonly distribution?: Distribution;
1048
1152
  }) => VerifyEnvelope;
1153
+ /**
1154
+ * Issue #138's batch success envelope, schema 1, the same snake_case
1155
+ * convention as `VerifyEnvelope`. `concepts` carries every concept
1156
+ * `okfit verify --all`/`--type` attested (or would attest under a dry run),
1157
+ * in write order; `skipped` carries every candidate it declined, with why.
1158
+ *
1159
+ * @public
1160
+ */
1161
+ export declare const VerifyBatchEnvelope: Schema.Struct<{
1162
+ readonly schema: Schema.Literal<1>;
1163
+ readonly okfit_version: Schema.String;
1164
+ readonly engine_version: Schema.String;
1165
+ readonly distribution: Schema.NullOr<Schema.Struct<{
1166
+ readonly name: Schema.String;
1167
+ readonly version: Schema.String;
1168
+ }>>;
1169
+ readonly verified_by: Schema.String;
1170
+ readonly verified_at: Schema.String;
1171
+ readonly concepts: Schema.$Array<Schema.Struct<{
1172
+ readonly id: Schema.String;
1173
+ readonly path: Schema.String;
1174
+ }>>;
1175
+ readonly skipped: Schema.$Array<Schema.Struct<{
1176
+ readonly id: Schema.String;
1177
+ readonly reason: Schema.Literals<readonly ["draft", "already-verified"]>;
1178
+ }>>;
1179
+ readonly dry_run: Schema.Boolean;
1180
+ readonly exit_code: Schema.Literal<0>;
1181
+ }>;
1182
+ /** @public */
1183
+ export type VerifyBatchEnvelope = typeof VerifyBatchEnvelope.Type;
1184
+ /**
1185
+ * `concepts[].path` is already the display form, the same convention
1186
+ * {@link verifyEnvelope} uses for its own `path`.
1187
+ *
1188
+ * @public
1189
+ */
1190
+ export declare const verifyBatchEnvelope: (input: {
1191
+ readonly okfitVersion: string;
1192
+ readonly by: string;
1193
+ readonly at: string;
1194
+ readonly concepts: ReadonlyArray<{
1195
+ readonly id: string;
1196
+ readonly path: string;
1197
+ }>;
1198
+ readonly skipped: ReadonlyArray<{
1199
+ readonly id: string;
1200
+ readonly reason: "draft" | "already-verified";
1201
+ }>;
1202
+ readonly dryRun: boolean;
1203
+ readonly distribution?: Distribution;
1204
+ }) => VerifyBatchEnvelope;
1049
1205
  //#endregion
1050
1206
  //#region src/stale/run.d.ts
1051
1207
  /** @public */
@@ -1180,6 +1336,51 @@ interface VerifyResult {
1180
1336
  /** The exact bytes `splice`'s edit would insert, written or not. */
1181
1337
  readonly fragment: string;
1182
1338
  }
1339
+ /**
1340
+ * Issue #138: options for {@link runVerifyBatch}. `types` restricts the
1341
+ * selected concept types; empty selects every type whose `config.types`
1342
+ * declaration sets `require_verified = true`.
1343
+ *
1344
+ * @public
1345
+ */
1346
+ interface VerifyBatchOptions {
1347
+ readonly bundleRoot: string;
1348
+ readonly projectRoot: string;
1349
+ readonly config: OkfitConfig;
1350
+ readonly at: DateTime.Utc;
1351
+ readonly dryRun: boolean;
1352
+ /** Restrict to these types; empty = every type with `require_verified = true`. */
1353
+ readonly types: ReadonlyArray<string>;
1354
+ }
1355
+ /**
1356
+ * Why {@link runVerifyBatch} skipped a candidate concept: `"draft"` for
1357
+ * `status === "draft"`, `"already-verified"` when the resolved actor already
1358
+ * carries a `verified` entry.
1359
+ *
1360
+ * @public
1361
+ */
1362
+ type VerifyBatchSkipReason = "draft" | "already-verified";
1363
+ /**
1364
+ * The result of {@link runVerifyBatch}.
1365
+ *
1366
+ * @public
1367
+ */
1368
+ interface VerifyBatchResult {
1369
+ readonly bundleRoot: string;
1370
+ readonly by: string;
1371
+ readonly at: string;
1372
+ readonly dryRun: boolean;
1373
+ /** In bundle iteration order; each carries the exact fragment written (or that would be). */
1374
+ readonly verified: ReadonlyArray<{
1375
+ readonly id: string;
1376
+ readonly conceptPath: string;
1377
+ readonly fragment: string;
1378
+ }>;
1379
+ readonly skipped: ReadonlyArray<{
1380
+ readonly id: string;
1381
+ readonly reason: VerifyBatchSkipReason;
1382
+ }>;
1383
+ }
1183
1384
  /**
1184
1385
  * Contract §2.3 steps 6–15. Loads the bundle, resolves the id, resolves the
1185
1386
  * human actor from git, splices exactly one entry into the concept's
@@ -1194,12 +1395,52 @@ export declare const runVerify: (options: VerifyOptions) => Effect.Effect<{
1194
1395
  id: ConceptId;
1195
1396
  bundleRoot: string;
1196
1397
  conceptPath: string;
1197
- by: import("@okfit/core").Actor;
1398
+ by: Actor;
1198
1399
  at: string;
1199
1400
  priorAt: string[];
1200
1401
  dryRun: boolean;
1201
1402
  fragment: string;
1202
1403
  }, import("effect/PlatformError").PlatformError | VerifyConceptNotFoundError | VerifyUnsupportedFrontmatterError | import("@effected/yaml").YamlParseError | import("@okfit/core").BundleLoadError | import("@okfit/profiles").GeneratedByError, FileSystem.FileSystem | import("@effected/git").Git | Path.Path>;
1404
+ /**
1405
+ * Issue #138. Attests every concept selected by `options.types` (or, when
1406
+ * empty, every type whose declaration sets `require_verified = true`) that
1407
+ * is not a draft and does not already carry a `verified` entry by the
1408
+ * resolved actor. Every candidate is located FIRST -- an unsupported
1409
+ * `verified` shape on any one of them fails the whole batch with nothing
1410
+ * written, mirroring `runVerify`'s own fail-closed rule at batch scale.
1411
+ *
1412
+ * @public
1413
+ */
1414
+ export declare const runVerifyBatch: (options: VerifyBatchOptions) => Effect.Effect<{
1415
+ bundleRoot: string;
1416
+ by: Actor;
1417
+ at: string;
1418
+ dryRun: boolean;
1419
+ verified: {
1420
+ id: string;
1421
+ conceptPath: string;
1422
+ fragment: string;
1423
+ }[];
1424
+ skipped: {
1425
+ readonly id: string;
1426
+ readonly reason: VerifyBatchSkipReason;
1427
+ }[];
1428
+ }, import("effect/PlatformError").PlatformError | VerifySelectionError | VerifyUnsupportedFrontmatterError | import("@effected/yaml").YamlParseError | import("@okfit/core").BundleLoadError | import("@okfit/profiles").GeneratedByError, FileSystem.FileSystem | import("@effected/git").Git | Path.Path>;
1429
+ //#endregion
1430
+ //#region src/version.d.ts
1431
+ /**
1432
+ * The version this engine reports as `engine_version` in every JSON
1433
+ * envelope. `@savvy-web/bundler` replaces `process.env.__PACKAGE_VERSION__`
1434
+ * with this package's own version at build time (K-32), so a release can
1435
+ * never desync from the printed version. `"0.0.0"` is the unbuilt-source
1436
+ * fallback and reads as dev mode. This is the ONE `process` read this
1437
+ * package's own `boundaries.test.ts` allowlists — see that file and this
1438
+ * package's `CLAUDE.md` for why it is safe here even though every other
1439
+ * `process` read is forbidden.
1440
+ *
1441
+ * @public
1442
+ */
1443
+ export declare const ENGINE_VERSION: string;
1203
1444
  //#endregion
1204
- export type { ContextResult, ContextRunOptions, DiagnosticSource, DiscoveredConfig, GraphRunOptions, GraphRunResult, RenderedDiagnostic, ResolveProjectConfigInput, ResolvedProjectConfig, RunOptions, RunResult, ScaffoldFile, ScaffoldOptions, StaleRunOptions, StaleRunResult, SyncMode, SyncModeResult, SyncOptions, SyncResult, Tally, VerifyOptions, VerifyResult };
1445
+ export type { ContextResult, ContextRunOptions, DiagnosticSource, DiscoveredConfig, Distribution, GraphRunOptions, GraphRunResult, RenderedDiagnostic, ResolveProjectConfigInput, ResolvedProjectConfig, RunOptions, RunResult, ScaffoldFile, ScaffoldOptions, StaleRunOptions, StaleRunResult, SyncMode, SyncModeResult, SyncOptions, SyncResult, Tally, VerifyBatchOptions, VerifyBatchResult, VerifyBatchSkipReason, VerifyOptions, VerifyResult };
1205
1446
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,22 +1,24 @@
1
1
  import { resolveBundleRoot, resolveProjectRoot } from "./config/anchor.js";
2
- import { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, VerifyConceptNotFoundError, VerifyUnsupportedFrontmatterError } from "./errors.js";
2
+ import { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, SyncStagedLogError, VerifyConceptNotFoundError, VerifySelectionError, VerifyUnsupportedFrontmatterError } from "./errors.js";
3
3
  import { buildConfigLayer, provideConfig } from "./config/layer.js";
4
4
  import { DEFAULT_PROFILE_NAME, resolveProjectConfig } from "./config/resolve.js";
5
5
  import { runContext } from "./context/run.js";
6
6
  import { runGraph } from "./graph/run.js";
7
- import { CONFIG_RELATIVE_PATH, SCHEMA_DIRECTIVE, configValue, files, targetPaths } from "./init/scaffold.js";
7
+ import { CONFIG_RELATIVE_PATH, configValue, files, targetPaths } from "./init/scaffold.js";
8
8
  import { OkfitPlatform } from "./platform.js";
9
9
  import { ContextEnvelope, ContextField, ContextFieldValue, ContextTag, ContextType, contextEnvelope } from "./render/context.js";
10
+ import { DistributionField } from "./render/distribution.js";
10
11
  import { forDiagnostics, tally } from "./render/exit.js";
12
+ import { ENGINE_VERSION } from "./version.js";
11
13
  import { GraphEdgeEnvelope, GraphEnvelope, GraphNodeEnvelope, GraphSummary, graphEnvelope } from "./render/graph.js";
12
14
  import { collect, sort } from "./render/sort.js";
13
15
  import { JsonDiagnostic, JsonEnvelope, JsonErrorEnvelope, JsonSummary, json, jsonError } from "./render/json.js";
14
16
  import { StaleEnvelope, StaleItem, StaleSummary, staleEnvelope } from "./render/stale.js";
15
17
  import { SkipReason, runSync } from "./sync/run.js";
16
18
  import { SyncEnvelope, SyncModeEnvelope, syncEnvelope } from "./render/sync.js";
17
- import { VerifyEnvelope, verifyEnvelope } from "./render/verify.js";
19
+ import { VerifyBatchEnvelope, VerifyEnvelope, verifyBatchEnvelope, verifyEnvelope } from "./render/verify.js";
18
20
  import { runStale } from "./stale/run.js";
19
21
  import { Now, run } from "./validate/run.js";
20
- import { runVerify } from "./verify/run.js";
22
+ import { runVerify, runVerifyBatch } from "./verify/run.js";
21
23
 
22
- export { CONFIG_RELATIVE_PATH, ConfigMalformedError, ConfigPathNotFoundError, ContextEnvelope, ContextField, ContextFieldValue, ContextTag, ContextType, DEFAULT_PROFILE_NAME, GraphEdgeEnvelope, GraphEnvelope, GraphNodeEnvelope, GraphSummary, InitOverwriteError, JsonDiagnostic, JsonEnvelope, JsonErrorEnvelope, JsonSummary, Now, OkfitPlatform, SCHEMA_DIRECTIVE, SkipReason, StaleEnvelope, StaleItem, StaleSummary, SyncEnvelope, SyncModeEnvelope, VerifyConceptNotFoundError, VerifyEnvelope, VerifyUnsupportedFrontmatterError, buildConfigLayer, collect, configValue, contextEnvelope, files, forDiagnostics, graphEnvelope, json, jsonError, provideConfig, resolveBundleRoot, resolveProjectConfig, resolveProjectRoot, run, runContext, runGraph, runStale, runSync, runVerify, sort, staleEnvelope, syncEnvelope, tally, targetPaths, verifyEnvelope };
24
+ export { CONFIG_RELATIVE_PATH, ConfigMalformedError, ConfigPathNotFoundError, ContextEnvelope, ContextField, ContextFieldValue, ContextTag, ContextType, DEFAULT_PROFILE_NAME, DistributionField, ENGINE_VERSION, GraphEdgeEnvelope, GraphEnvelope, GraphNodeEnvelope, GraphSummary, InitOverwriteError, JsonDiagnostic, JsonEnvelope, JsonErrorEnvelope, JsonSummary, Now, OkfitPlatform, SkipReason, StaleEnvelope, StaleItem, StaleSummary, SyncEnvelope, SyncModeEnvelope, SyncStagedLogError, VerifyBatchEnvelope, VerifyConceptNotFoundError, VerifyEnvelope, VerifySelectionError, VerifyUnsupportedFrontmatterError, buildConfigLayer, collect, configValue, contextEnvelope, files, forDiagnostics, graphEnvelope, json, jsonError, provideConfig, resolveBundleRoot, resolveProjectConfig, resolveProjectRoot, run, runContext, runGraph, runStale, runSync, runVerify, runVerifyBatch, sort, staleEnvelope, syncEnvelope, tally, targetPaths, verifyBatchEnvelope, verifyEnvelope };
package/init/scaffold.js CHANGED
@@ -21,8 +21,6 @@ const PROJECT_CONFIG_NAMES = [
21
21
  "okfit.toml",
22
22
  ".config/okfit.toml"
23
23
  ];
24
- /** C-22's directive, plus the blank line Tombi requires. @public */
25
- const SCHEMA_DIRECTIVE = "#:schema https://raw.githubusercontent.com/spencerbeggs/okfit/main/schemas/config/okfit-1.0.0.json\n\n";
26
24
  /**
27
25
  * K-23: the THIN override only — never the merged config. `bundle.path` is
28
26
  * the bundle root relative to the project root; `extensions: {}` satisfies
@@ -171,4 +169,4 @@ const files = (options) => Effect.gen(function* () {
171
169
  });
172
170
 
173
171
  //#endregion
174
- export { CONFIG_RELATIVE_PATH, PROJECT_CONFIG_NAMES, SCHEMA_DIRECTIVE, configValue, files, targetPaths };
172
+ export { CONFIG_RELATIVE_PATH, PROJECT_CONFIG_NAMES, configValue, files, targetPaths };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okfit/engine",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "The okfit engine: platform layer, config discovery, and the validate, verify, sync, init and context programs shared by the okfit CLI and MCP server.",
6
6
  "keywords": [
@@ -46,8 +46,8 @@
46
46
  "@effected/walker": "^0.9.0",
47
47
  "@effected/xdg": "^0.5.2",
48
48
  "@effected/yaml": "^0.15.1",
49
- "@okfit/core": "0.5.0",
50
- "@okfit/profiles": "0.7.0",
49
+ "@okfit/core": "0.7.0",
50
+ "@okfit/profiles": "0.7.2",
51
51
  "effect": "4.0.0-rc.115"
52
52
  },
53
53
  "engines": {
package/render/context.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { CONFIG_SCHEMA_VERSION } from "@okfit/core";
1
2
  import { Schema } from "effect";
2
3
 
3
4
  //#region src/render/context.ts
@@ -64,10 +65,15 @@ const ContextTag = Schema.Struct({
64
65
  * consumer can tell "no profile configured" apart from "an unknown profile
65
66
  * was configured".
66
67
  *
68
+ * `config_schema_version` is `@okfit/core`'s `CONFIG_SCHEMA_VERSION`,
69
+ * stamped by {@link contextEnvelope} itself -- callers cannot pass or fake
70
+ * it (okfit #137).
71
+ *
67
72
  * @public
68
73
  */
69
74
  const ContextEnvelope = Schema.Struct({
70
75
  schema: Schema.Literal(1),
76
+ config_schema_version: Schema.String,
71
77
  project_root: Schema.String,
72
78
  bundle_root: Schema.String,
73
79
  config_path: Schema.NullOr(Schema.String),
@@ -89,6 +95,7 @@ const ContextEnvelope = Schema.Struct({
89
95
  */
90
96
  const contextEnvelope = (input) => ({
91
97
  schema: 1,
98
+ config_schema_version: CONFIG_SCHEMA_VERSION,
92
99
  project_root: input.projectRoot,
93
100
  bundle_root: input.bundleRoot,
94
101
  config_path: input.configPath,
@@ -0,0 +1,11 @@
1
+ import { Schema } from "effect";
2
+
3
+ //#region src/render/distribution.ts
4
+ /** Every envelope's `distribution` field: a `Distribution` or `null`. @public */
5
+ const DistributionField = Schema.NullOr(Schema.Struct({
6
+ name: Schema.String,
7
+ version: Schema.String
8
+ }));
9
+
10
+ //#endregion
11
+ export { DistributionField };
package/render/graph.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { DistributionField } from "./distribution.js";
2
+ import { ENGINE_VERSION } from "../version.js";
1
3
  import { Schema } from "effect";
2
4
 
3
5
  //#region src/render/graph.ts
@@ -33,7 +35,9 @@ const GraphSummary = Schema.Struct({
33
35
  const GraphEnvelope = Schema.Struct({
34
36
  schema: Schema.Literal(1),
35
37
  okfit_version: Schema.String,
38
+ engine_version: Schema.String,
36
39
  producer: Schema.String,
40
+ distribution: DistributionField,
37
41
  okf_version: Schema.String,
38
42
  root: Schema.String,
39
43
  profile: Schema.NullOr(Schema.String),
@@ -61,7 +65,9 @@ const toEdge = (edge) => ({
61
65
  const graphEnvelope = (input) => ({
62
66
  schema: 1,
63
67
  okfit_version: input.okfitVersion,
68
+ engine_version: ENGINE_VERSION,
64
69
  producer: input.producer,
70
+ distribution: input.distribution ?? null,
65
71
  okf_version: input.okfVersion,
66
72
  root: input.root,
67
73
  profile: input.profile,