@habitat-ai/service 0.2.0 → 0.2.2

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.
@@ -1,16 +1,15 @@
1
1
  import { MAX_SOURCE_INVENTORY_ENTRIES } from "@habitat-ai/resource-source-inventory";
2
2
  import { Effect } from "effect";
3
3
  import { parse as parseToml } from "smol-toml";
4
- import { admitBlueprintSource, admitCompatibilityIndex, admitCompatibilityRule, admitInstanceSource, admitPolicyPackManifest, admitPolicyPackPackageJson, admitPolicyPackSelection, referencedRepositoryPaths, rejected, resolveCatalog, } from "../model/policy/catalog.js";
5
- import { completedCheck, evaluatedApplication, evaluatedStructureApplication, extractGritProgram, failedApplication, failedStructureApplication, selectCheckApplications, } from "../model/policy/check.js";
4
+ import { admitBlueprintSource, admitCompatibilityBaseline, admitCompatibilityIndex, admitCompatibilityRule, admitInstanceSource, admitPolicyPackManifest, admitPolicyPackPackageJson, admitPolicyPackSelection, referencedRepositoryPaths, rejected, resolveCatalog, } from "../model/policy/catalog.js";
5
+ import { completedCheck, evaluatedApplication, evaluatedStructureApplication, extractGritProgram, failedApplication, failedStructureApplication, isCompatibilityRule, notApplicableApplication, selectCheckApplications, } from "../model/policy/check.js";
6
6
  import { admitStructureDocument, evaluateStructurePlan, isHabitatStructureApplication, makeStructureUniverse, planStructureEvaluation, structureChildObservationPaths, } from "../model/policy/structure.js";
7
7
  import { module } from "../module.js";
8
8
  const authorityGlobs = [
9
9
  { kind: "blueprint", pattern: ".habitat/blueprints/*/blueprint.toml" },
10
- // Effect's glob provider requires a dynamic pattern even for this exact optional file.
11
- { kind: "index", pattern: ".habitat/{index.json}" },
12
10
  { kind: "rule", pattern: ".habitat/**/rule.json" },
13
11
  ];
12
+ const compatibilityIndexAuthorityPath = ".habitat/index.json";
14
13
  const excludedDirectorySegments = new Set([
15
14
  ".git",
16
15
  ".nx",
@@ -23,6 +22,13 @@ const excludedDirectorySegments = new Set([
23
22
  "vendor",
24
23
  ]);
25
24
  const excludedRepositoryGlobs = [...excludedDirectorySegments].map((segment) => `**/${segment}/**`);
25
+ const compatibilityProtectedRoots = [
26
+ ".git",
27
+ ".habitat/cache/patterns",
28
+ "dist",
29
+ "node_modules",
30
+ "tools/habitat/dist",
31
+ ];
26
32
  const MAX_MANIFEST_DIRECTORIES = 50_000;
27
33
  function resolveCurrentCatalog(context) {
28
34
  return Effect.gen(function* () {
@@ -119,6 +125,13 @@ function resolveCurrentCatalog(context) {
119
125
  pathsByKind[kind].push(relativePath);
120
126
  }
121
127
  }
128
+ const compatibilityIndexStat = yield* Effect.result(fileSystem.stat(path.resolve(workspaceRoot, compatibilityIndexAuthorityPath)));
129
+ if (compatibilityIndexStat._tag === "Success") {
130
+ pathsByKind.index.push(compatibilityIndexAuthorityPath);
131
+ }
132
+ else if (!isNotFound(compatibilityIndexStat.failure)) {
133
+ enumerationIssues.push(filesystemIssue(compatibilityIndexStat.failure, compatibilityIndexAuthorityPath, "inspect compatibility index", "Compatibility index does not exist."));
134
+ }
122
135
  // The installed glob provider skips hidden directories, so manifests use a confined traversal.
123
136
  const manifestCandidates = [];
124
137
  const pendingDirectories = [{ relativePath: "", realPath: workspaceRealRoot }];
@@ -333,10 +346,69 @@ function resolveCurrentCatalog(context) {
333
346
  continue;
334
347
  }
335
348
  const admitted = admitCompatibilityRule(parsed.success, relativePath);
336
- if (admitted.ok)
337
- compatibilityRules.push(admitted.source);
338
- else
349
+ if (!admitted.ok) {
339
350
  issues.push(...admitted.issues);
351
+ continue;
352
+ }
353
+ const baselinePath = admitted.source.rule.supportFiles.baseline;
354
+ const absoluteBaselinePath = path.resolve(workspaceRoot, baselinePath);
355
+ if (!isContained(workspaceRoot, absoluteBaselinePath, path)) {
356
+ issues.push({
357
+ code: "authority-path-escape",
358
+ path: baselinePath,
359
+ message: "Compatibility baseline escapes workspaceRoot.",
360
+ });
361
+ continue;
362
+ }
363
+ const baselineRealPath = yield* Effect.result(fileSystem.realPath(absoluteBaselinePath));
364
+ if (baselineRealPath._tag === "Failure") {
365
+ issues.push(filesystemIssue(baselineRealPath.failure, baselinePath, "resolve compatibility baseline", "Compatibility baseline does not exist."));
366
+ continue;
367
+ }
368
+ if (!isContained(workspaceRealRoot, baselineRealPath.success, path)) {
369
+ issues.push({
370
+ code: "authority-path-escape",
371
+ path: baselinePath,
372
+ message: "Compatibility baseline escapes workspaceRoot through a symbolic link.",
373
+ });
374
+ continue;
375
+ }
376
+ const baselineStat = yield* Effect.result(fileSystem.stat(baselineRealPath.success));
377
+ if (baselineStat._tag === "Failure") {
378
+ issues.push(filesystemIssue(baselineStat.failure, baselinePath, "inspect compatibility baseline", "Compatibility baseline does not exist."));
379
+ continue;
380
+ }
381
+ if (baselineStat.success.type !== "File") {
382
+ issues.push({
383
+ code: "authority-path-kind-mismatch",
384
+ path: baselinePath,
385
+ message: "Compatibility baseline must be a regular file.",
386
+ });
387
+ continue;
388
+ }
389
+ const baselineRead = yield* Effect.result(fileSystem.readFileString(baselineRealPath.success));
390
+ if (baselineRead._tag === "Failure") {
391
+ issues.push(filesystemIssue(baselineRead.failure, baselinePath, "read compatibility baseline", "Compatibility baseline does not exist."));
392
+ continue;
393
+ }
394
+ const baselineParsed = yield* Effect.result(Effect.try({
395
+ try: () => JSON.parse(baselineRead.success),
396
+ catch: (cause) => cause,
397
+ }));
398
+ if (baselineParsed._tag === "Failure") {
399
+ issues.push({
400
+ code: "authority-json-invalid",
401
+ path: baselinePath,
402
+ message: "Compatibility baseline is not valid JSON.",
403
+ });
404
+ continue;
405
+ }
406
+ const baseline = admitCompatibilityBaseline(baselineParsed.success, baselinePath);
407
+ if (!baseline.ok) {
408
+ issues.push(...baseline.issues);
409
+ continue;
410
+ }
411
+ compatibilityRules.push({ ...admitted.source, baseline: baseline.value });
340
412
  }
341
413
  if (issues.length > 0)
342
414
  return rejected(issues);
@@ -572,7 +644,19 @@ const check = module.check.effect(function* ({ context, input }) {
572
644
  reports.push(failedApplication(application, "PatternInvalid", program.detail));
573
645
  continue;
574
646
  }
575
- const subjects = resolvedSubjects(application, context.workspaceRoot, context.path);
647
+ const subjectPreparation = yield* prepareGritSubjects(application, context.workspaceRoot, context.fileSystem, context.path);
648
+ if (subjectPreparation.kind === "failed") {
649
+ reports.push(failedApplication(application, "SetupFailed", subjectPreparation.detail));
650
+ continue;
651
+ }
652
+ if (subjectPreparation.kind === "not-applicable") {
653
+ if (!isCompatibilityRule(application)) {
654
+ return yield* Effect.die(new Error("Version-three Grit applications cannot be not applicable."));
655
+ }
656
+ reports.push(notApplicableApplication(application));
657
+ continue;
658
+ }
659
+ const subjects = subjectPreparation.subjects;
576
660
  const evaluation = yield* Effect.result(context.ruleEvaluation.evaluate({
577
661
  program: program.program,
578
662
  subjectPaths: subjects.map((subject) => subject.absolutePath),
@@ -623,6 +707,113 @@ function hasExactCauseCode(error, code) {
623
707
  const cause = "cause" in error.reason ? error.reason.cause : undefined;
624
708
  return typeof cause === "object" && cause !== null && "code" in cause && cause.code === code;
625
709
  }
710
+ function prepareGritSubjects(application, workspaceRoot, fileSystem, path) {
711
+ if (!isCompatibilityRule(application)) {
712
+ return Effect.succeed({
713
+ kind: "ready",
714
+ subjects: resolvedSubjects(application, workspaceRoot, path),
715
+ });
716
+ }
717
+ return Effect.gen(function* () {
718
+ const workspaceRealPath = yield* Effect.result(fileSystem.realPath(workspaceRoot));
719
+ if (workspaceRealPath._tag === "Failure") {
720
+ return {
721
+ kind: "failed",
722
+ detail: "Unable to canonicalize the compatibility workspace root.",
723
+ };
724
+ }
725
+ const authority = resolvedSubjects(application, workspaceRoot, path);
726
+ for (const root of authority) {
727
+ const canonical = yield* Effect.result(fileSystem.realPath(root.absolutePath));
728
+ if (canonical._tag === "Failure") {
729
+ return {
730
+ kind: "failed",
731
+ detail: `Unable to canonicalize compatibility acquisition root "${toRepositoryPath(path.relative(workspaceRoot, root.absolutePath), path.sep)}".`,
732
+ };
733
+ }
734
+ const expectedCanonical = path.resolve(workspaceRealPath.success, path.relative(workspaceRoot, root.absolutePath));
735
+ if (canonical.success !== expectedCanonical ||
736
+ !isContained(workspaceRealPath.success, canonical.success, path)) {
737
+ return {
738
+ kind: "failed",
739
+ detail: `Compatibility acquisition root "${toRepositoryPath(path.relative(workspaceRoot, root.absolutePath), path.sep)}" is a symbolic link; compatibility checks accept direct workspace roots only.`,
740
+ };
741
+ }
742
+ }
743
+ const resolvedCoveragePatterns = application.coveragePatterns.map((pattern) => path.resolve(workspaceRoot, pattern));
744
+ const compatibilityExcludes = [path.resolve(workspaceRoot, "**/node_modules/**")];
745
+ const globAttempts = yield* Effect.all(resolvedCoveragePatterns.map((pattern) => Effect.result(fileSystem.glob(pattern, { exclude: compatibilityExcludes }))));
746
+ const failedGlob = globAttempts.find((attempt) => attempt._tag === "Failure");
747
+ if (failedGlob?._tag === "Failure") {
748
+ return {
749
+ kind: "failed",
750
+ detail: "Unable to enumerate compatibility exact-path coverage.",
751
+ };
752
+ }
753
+ const directAttempts = yield* Effect.all(resolvedCoveragePatterns.map((pattern) => Effect.result(fileSystem.stat(pattern))));
754
+ const failedDirect = directAttempts.find((attempt) => attempt._tag === "Failure" && !isNotFound(attempt.failure));
755
+ if (failedDirect?._tag === "Failure") {
756
+ return {
757
+ kind: "failed",
758
+ detail: "Unable to inspect compatibility exact-path coverage.",
759
+ };
760
+ }
761
+ const candidates = stablePaths([
762
+ ...globAttempts.flatMap((attempt) => attempt._tag === "Success"
763
+ ? attempt.success.map((candidate) => path.isAbsolute(candidate)
764
+ ? path.resolve(candidate)
765
+ : path.resolve(workspaceRoot, candidate))
766
+ : []),
767
+ ...directAttempts.flatMap((attempt, index) => attempt._tag === "Success" && attempt.success.type === "File"
768
+ ? [resolvedCoveragePatterns[index]]
769
+ : []),
770
+ ].filter((candidate) => candidate !== undefined)).filter((candidate) => !isCompatibilityProtectedSubject(candidate, workspaceRoot, path) &&
771
+ authority.some((root) => root.kind === "file"
772
+ ? candidate === root.absolutePath
773
+ : isContained(root.absolutePath, candidate, path)));
774
+ const subjects = [];
775
+ for (const candidate of candidates) {
776
+ const canonical = yield* Effect.result(fileSystem.realPath(candidate));
777
+ if (canonical._tag === "Failure") {
778
+ if (isNotFound(canonical.failure))
779
+ continue;
780
+ return {
781
+ kind: "failed",
782
+ detail: `Unable to canonicalize compatibility subject "${toRepositoryPath(path.relative(workspaceRoot, candidate), path.sep)}".`,
783
+ };
784
+ }
785
+ const expectedCanonical = path.resolve(workspaceRealPath.success, path.relative(workspaceRoot, candidate));
786
+ if (canonical.success !== expectedCanonical ||
787
+ !isContained(workspaceRealPath.success, canonical.success, path)) {
788
+ return {
789
+ kind: "failed",
790
+ detail: `Exact coverage selected symbolic link "${toRepositoryPath(path.relative(workspaceRoot, candidate), path.sep)}"; compatibility checks accept regular files only.`,
791
+ };
792
+ }
793
+ const stat = yield* Effect.result(fileSystem.stat(canonical.success));
794
+ if (stat._tag === "Failure") {
795
+ if (isNotFound(stat.failure))
796
+ continue;
797
+ return {
798
+ kind: "failed",
799
+ detail: `Unable to inspect compatibility subject "${toRepositoryPath(path.relative(workspaceRoot, candidate), path.sep)}".`,
800
+ };
801
+ }
802
+ if (stat.success.type === "File") {
803
+ subjects.push({ absolutePath: candidate, kind: "file" });
804
+ }
805
+ }
806
+ return subjects.length === 0
807
+ ? { kind: "not-applicable" }
808
+ : { kind: "ready", subjects };
809
+ });
810
+ }
811
+ function isCompatibilityProtectedSubject(candidate, workspaceRoot, path) {
812
+ const relative = toRepositoryPath(path.relative(workspaceRoot, candidate), path.sep);
813
+ if (relative.split("/").includes("node_modules"))
814
+ return true;
815
+ return compatibilityProtectedRoots.some((root) => relative === root || relative.startsWith(`${root}/`));
816
+ }
626
817
  function resolvedSubjects(application, workspaceRoot, path) {
627
818
  const subjects = new Map();
628
819
  for (const entry of application.runner.acquisition.entries) {
@@ -157,9 +157,59 @@ export declare const router: {
157
157
  schemaVersion: import("typebox").TLiteral<2>;
158
158
  ownerRoots: import("typebox").TRecord<"^.*$", import("typebox").TString>;
159
159
  rules: import("typebox").TArray<import("typebox").TObject<{
160
- id: import("typebox").TString;
160
+ ruleId: import("typebox").TString;
161
161
  ownerProject: import("typebox").TString;
162
162
  manifestPath: import("typebox").TString;
163
+ lane: import("typebox").TLiteral<"enforced">;
164
+ message: import("typebox").TString;
165
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
166
+ provenance: import("typebox").TObject<{
167
+ kind: import("typebox").TLiteral<"local">;
168
+ authorityRoot: import("typebox").TString;
169
+ relativePath: import("typebox").TString;
170
+ }>;
171
+ coveragePatterns: import("typebox").TArray<import("typebox").TString>;
172
+ baseline: import("typebox").TObject<{
173
+ provenance: import("typebox").TObject<{
174
+ kind: import("typebox").TLiteral<"local">;
175
+ authorityRoot: import("typebox").TString;
176
+ relativePath: import("typebox").TString;
177
+ }>;
178
+ relativePath: import("typebox").TString;
179
+ absolutePath: import("typebox").TString;
180
+ }>;
181
+ runner: import("typebox").TUnion<[import("typebox").TObject<{
182
+ name: import("typebox").TLiteral<"habitat">;
183
+ mode: import("typebox").TLiteral<"structure">;
184
+ structure: import("typebox").TObject<{
185
+ provenance: import("typebox").TObject<{
186
+ kind: import("typebox").TLiteral<"local">;
187
+ authorityRoot: import("typebox").TString;
188
+ relativePath: import("typebox").TString;
189
+ }>;
190
+ relativePath: import("typebox").TString;
191
+ absolutePath: import("typebox").TString;
192
+ }>;
193
+ }>, import("typebox").TObject<{
194
+ name: import("typebox").TLiteral<"grit">;
195
+ pattern: import("typebox").TObject<{
196
+ provenance: import("typebox").TObject<{
197
+ kind: import("typebox").TLiteral<"local">;
198
+ authorityRoot: import("typebox").TString;
199
+ relativePath: import("typebox").TString;
200
+ }>;
201
+ relativePath: import("typebox").TString;
202
+ absolutePath: import("typebox").TString;
203
+ }>;
204
+ patternName: import("typebox").TString;
205
+ acquisition: import("typebox").TObject<{
206
+ kind: import("typebox").TLiteral<"check">;
207
+ entries: import("typebox").TArray<import("typebox").TObject<{
208
+ kind: import("typebox").TUnion<[import("typebox").TLiteral<"directory">, import("typebox").TLiteral<"file">]>;
209
+ path: import("typebox").TString;
210
+ }>>;
211
+ }>;
212
+ }>]>;
163
213
  }>>;
164
214
  }>;
165
215
  }>;
@@ -236,6 +286,42 @@ export declare const router: {
236
286
  severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
237
287
  baselined: import("typebox").TLiteral<false>;
238
288
  }>>;
289
+ }>, import("typebox").TObject<{
290
+ ownerProject: import("typebox").TString;
291
+ instanceId: import("typebox").TNull;
292
+ ruleId: import("typebox").TString;
293
+ runner: import("typebox").TLiteral<"grit">;
294
+ lane: import("typebox").TUnion<[import("typebox").TLiteral<"enforced">, import("typebox").TLiteral<"advisory">]>;
295
+ locked: import("typebox").TLiteral<true>;
296
+ status: import("typebox").TUnion<[import("typebox").TLiteral<"pass">, import("typebox").TLiteral<"fail">, import("typebox").TLiteral<"advisory-findings">, import("typebox").TLiteral<"error">]>;
297
+ message: import("typebox").TString;
298
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
299
+ disposition: import("typebox").TUnion<[import("typebox").TObject<{
300
+ kind: import("typebox").TLiteral<"evaluated">;
301
+ }>, import("typebox").TObject<{
302
+ kind: import("typebox").TLiteral<"not-applicable">;
303
+ reason: import("typebox").TLiteral<"no-matched-acquisition-roots">;
304
+ }>, import("typebox").TObject<{
305
+ kind: import("typebox").TLiteral<"failed">;
306
+ reason: import("typebox").TUnion<[import("typebox").TUnion<[import("typebox").TLiteral<"InvalidInput">, import("typebox").TLiteral<"SetupFailed">, import("typebox").TLiteral<"ExecutionFailed">, import("typebox").TLiteral<"TimedOut">, import("typebox").TLiteral<"InvalidOutput">]>, import("typebox").TLiteral<"PatternReadFailed">, import("typebox").TLiteral<"PatternInvalid">, import("typebox").TLiteral<"FindingPathInvalid">]>;
307
+ detail: import("typebox").TString;
308
+ }>]>;
309
+ findings: import("typebox").TArray<import("typebox").TObject<{
310
+ path: import("typebox").TString;
311
+ start: import("typebox").TObject<{
312
+ line: import("typebox").TReadonly<import("typebox").TInteger>;
313
+ column: import("typebox").TReadonly<import("typebox").TInteger>;
314
+ offset: import("typebox").TReadonly<import("typebox").TInteger>;
315
+ }>;
316
+ end: import("typebox").TObject<{
317
+ line: import("typebox").TReadonly<import("typebox").TInteger>;
318
+ column: import("typebox").TReadonly<import("typebox").TInteger>;
319
+ offset: import("typebox").TReadonly<import("typebox").TInteger>;
320
+ }>;
321
+ message: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
322
+ severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
323
+ baselined: import("typebox").TLiteral<false>;
324
+ }>>;
239
325
  }>, import("typebox").TObject<{
240
326
  ownerProject: import("typebox").TString;
241
327
  instanceId: import("typebox").TString;
@@ -260,6 +346,30 @@ export declare const router: {
260
346
  severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
261
347
  baselined: import("typebox").TLiteral<false>;
262
348
  }>>;
349
+ }>, import("typebox").TObject<{
350
+ ownerProject: import("typebox").TString;
351
+ instanceId: import("typebox").TNull;
352
+ ruleId: import("typebox").TString;
353
+ runner: import("typebox").TLiteral<"habitat">;
354
+ lane: import("typebox").TUnion<[import("typebox").TLiteral<"enforced">, import("typebox").TLiteral<"advisory">]>;
355
+ locked: import("typebox").TLiteral<true>;
356
+ status: import("typebox").TUnion<[import("typebox").TLiteral<"pass">, import("typebox").TLiteral<"fail">, import("typebox").TLiteral<"advisory-findings">, import("typebox").TLiteral<"error">]>;
357
+ message: import("typebox").TString;
358
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
359
+ disposition: import("typebox").TUnion<[import("typebox").TObject<{
360
+ kind: import("typebox").TLiteral<"evaluated">;
361
+ }>, import("typebox").TObject<{
362
+ kind: import("typebox").TLiteral<"failed">;
363
+ reason: import("typebox").TUnion<[import("typebox").TLiteral<"StructureReadFailed">, import("typebox").TLiteral<"StructureInvalid">, import("typebox").TLiteral<"InventoryFailed">, import("typebox").TLiteral<"StructureObservationFailed">]>;
364
+ detail: import("typebox").TString;
365
+ }>]>;
366
+ findings: import("typebox").TArray<import("typebox").TObject<{
367
+ path: import("typebox").TString;
368
+ code: import("typebox").TUnion<[import("typebox").TLiteral<"root-missing">, import("typebox").TLiteral<"wrong-root-kind">, import("typebox").TLiteral<"missing-required-child">, import("typebox").TLiteral<"forbidden-child">, import("typebox").TLiteral<"unexpected-child">]>;
369
+ message: import("typebox").TString;
370
+ severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
371
+ baselined: import("typebox").TLiteral<false>;
372
+ }>>;
263
373
  }>]>>;
264
374
  }>]>>, object>;
265
375
  };
@@ -158,9 +158,59 @@ export declare const router: {
158
158
  schemaVersion: import("typebox").TLiteral<2>;
159
159
  ownerRoots: import("typebox").TRecord<"^.*$", import("typebox").TString>;
160
160
  rules: import("typebox").TArray<import("typebox").TObject<{
161
- id: import("typebox").TString;
161
+ ruleId: import("typebox").TString;
162
162
  ownerProject: import("typebox").TString;
163
163
  manifestPath: import("typebox").TString;
164
+ lane: import("typebox").TLiteral<"enforced">;
165
+ message: import("typebox").TString;
166
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
167
+ provenance: import("typebox").TObject<{
168
+ kind: import("typebox").TLiteral<"local">;
169
+ authorityRoot: import("typebox").TString;
170
+ relativePath: import("typebox").TString;
171
+ }>;
172
+ coveragePatterns: import("typebox").TArray<import("typebox").TString>;
173
+ baseline: import("typebox").TObject<{
174
+ provenance: import("typebox").TObject<{
175
+ kind: import("typebox").TLiteral<"local">;
176
+ authorityRoot: import("typebox").TString;
177
+ relativePath: import("typebox").TString;
178
+ }>;
179
+ relativePath: import("typebox").TString;
180
+ absolutePath: import("typebox").TString;
181
+ }>;
182
+ runner: import("typebox").TUnion<[import("typebox").TObject<{
183
+ name: import("typebox").TLiteral<"habitat">;
184
+ mode: import("typebox").TLiteral<"structure">;
185
+ structure: import("typebox").TObject<{
186
+ provenance: import("typebox").TObject<{
187
+ kind: import("typebox").TLiteral<"local">;
188
+ authorityRoot: import("typebox").TString;
189
+ relativePath: import("typebox").TString;
190
+ }>;
191
+ relativePath: import("typebox").TString;
192
+ absolutePath: import("typebox").TString;
193
+ }>;
194
+ }>, import("typebox").TObject<{
195
+ name: import("typebox").TLiteral<"grit">;
196
+ pattern: import("typebox").TObject<{
197
+ provenance: import("typebox").TObject<{
198
+ kind: import("typebox").TLiteral<"local">;
199
+ authorityRoot: import("typebox").TString;
200
+ relativePath: import("typebox").TString;
201
+ }>;
202
+ relativePath: import("typebox").TString;
203
+ absolutePath: import("typebox").TString;
204
+ }>;
205
+ patternName: import("typebox").TString;
206
+ acquisition: import("typebox").TObject<{
207
+ kind: import("typebox").TLiteral<"check">;
208
+ entries: import("typebox").TArray<import("typebox").TObject<{
209
+ kind: import("typebox").TUnion<[import("typebox").TLiteral<"directory">, import("typebox").TLiteral<"file">]>;
210
+ path: import("typebox").TString;
211
+ }>>;
212
+ }>;
213
+ }>]>;
164
214
  }>>;
165
215
  }>;
166
216
  }>;
@@ -237,6 +287,42 @@ export declare const router: {
237
287
  severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
238
288
  baselined: import("typebox").TLiteral<false>;
239
289
  }>>;
290
+ }>, import("typebox").TObject<{
291
+ ownerProject: import("typebox").TString;
292
+ instanceId: import("typebox").TNull;
293
+ ruleId: import("typebox").TString;
294
+ runner: import("typebox").TLiteral<"grit">;
295
+ lane: import("typebox").TUnion<[import("typebox").TLiteral<"enforced">, import("typebox").TLiteral<"advisory">]>;
296
+ locked: import("typebox").TLiteral<true>;
297
+ status: import("typebox").TUnion<[import("typebox").TLiteral<"pass">, import("typebox").TLiteral<"fail">, import("typebox").TLiteral<"advisory-findings">, import("typebox").TLiteral<"error">]>;
298
+ message: import("typebox").TString;
299
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
300
+ disposition: import("typebox").TUnion<[import("typebox").TObject<{
301
+ kind: import("typebox").TLiteral<"evaluated">;
302
+ }>, import("typebox").TObject<{
303
+ kind: import("typebox").TLiteral<"not-applicable">;
304
+ reason: import("typebox").TLiteral<"no-matched-acquisition-roots">;
305
+ }>, import("typebox").TObject<{
306
+ kind: import("typebox").TLiteral<"failed">;
307
+ reason: import("typebox").TUnion<[import("typebox").TUnion<[import("typebox").TLiteral<"InvalidInput">, import("typebox").TLiteral<"SetupFailed">, import("typebox").TLiteral<"ExecutionFailed">, import("typebox").TLiteral<"TimedOut">, import("typebox").TLiteral<"InvalidOutput">]>, import("typebox").TLiteral<"PatternReadFailed">, import("typebox").TLiteral<"PatternInvalid">, import("typebox").TLiteral<"FindingPathInvalid">]>;
308
+ detail: import("typebox").TString;
309
+ }>]>;
310
+ findings: import("typebox").TArray<import("typebox").TObject<{
311
+ path: import("typebox").TString;
312
+ start: import("typebox").TObject<{
313
+ line: import("typebox").TReadonly<import("typebox").TInteger>;
314
+ column: import("typebox").TReadonly<import("typebox").TInteger>;
315
+ offset: import("typebox").TReadonly<import("typebox").TInteger>;
316
+ }>;
317
+ end: import("typebox").TObject<{
318
+ line: import("typebox").TReadonly<import("typebox").TInteger>;
319
+ column: import("typebox").TReadonly<import("typebox").TInteger>;
320
+ offset: import("typebox").TReadonly<import("typebox").TInteger>;
321
+ }>;
322
+ message: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
323
+ severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
324
+ baselined: import("typebox").TLiteral<false>;
325
+ }>>;
240
326
  }>, import("typebox").TObject<{
241
327
  ownerProject: import("typebox").TString;
242
328
  instanceId: import("typebox").TString;
@@ -261,6 +347,30 @@ export declare const router: {
261
347
  severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
262
348
  baselined: import("typebox").TLiteral<false>;
263
349
  }>>;
350
+ }>, import("typebox").TObject<{
351
+ ownerProject: import("typebox").TString;
352
+ instanceId: import("typebox").TNull;
353
+ ruleId: import("typebox").TString;
354
+ runner: import("typebox").TLiteral<"habitat">;
355
+ lane: import("typebox").TUnion<[import("typebox").TLiteral<"enforced">, import("typebox").TLiteral<"advisory">]>;
356
+ locked: import("typebox").TLiteral<true>;
357
+ status: import("typebox").TUnion<[import("typebox").TLiteral<"pass">, import("typebox").TLiteral<"fail">, import("typebox").TLiteral<"advisory-findings">, import("typebox").TLiteral<"error">]>;
358
+ message: import("typebox").TString;
359
+ remediate: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
360
+ disposition: import("typebox").TUnion<[import("typebox").TObject<{
361
+ kind: import("typebox").TLiteral<"evaluated">;
362
+ }>, import("typebox").TObject<{
363
+ kind: import("typebox").TLiteral<"failed">;
364
+ reason: import("typebox").TUnion<[import("typebox").TLiteral<"StructureReadFailed">, import("typebox").TLiteral<"StructureInvalid">, import("typebox").TLiteral<"InventoryFailed">, import("typebox").TLiteral<"StructureObservationFailed">]>;
365
+ detail: import("typebox").TString;
366
+ }>]>;
367
+ findings: import("typebox").TArray<import("typebox").TObject<{
368
+ path: import("typebox").TString;
369
+ code: import("typebox").TUnion<[import("typebox").TLiteral<"root-missing">, import("typebox").TLiteral<"wrong-root-kind">, import("typebox").TLiteral<"missing-required-child">, import("typebox").TLiteral<"forbidden-child">, import("typebox").TLiteral<"unexpected-child">]>;
370
+ message: import("typebox").TString;
371
+ severity: import("typebox").TUnion<[import("typebox").TLiteral<"error">, import("typebox").TLiteral<"advisory">]>;
372
+ baselined: import("typebox").TLiteral<false>;
373
+ }>>;
264
374
  }>]>>;
265
375
  }>]>>, object>;
266
376
  };
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@habitat-ai/service",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/rawr-ai/rawr-hq-template.git",
8
+ "directory": "services/habitat"
9
+ },
5
10
  "type": "module",
6
11
  "packageManager": "bun@1.3.14",
7
12
  "files": [
@@ -19,13 +24,13 @@
19
24
  "test": "bun test test"
20
25
  },
21
26
  "dependencies": {
22
- "@habitat-ai/resource-rule-evaluation": "0.2.0",
23
- "@habitat-ai/resource-source-inventory": "0.2.0",
27
+ "@habitat-ai/resource-rule-evaluation": "0.2.2",
28
+ "@habitat-ai/resource-source-inventory": "0.2.2",
24
29
  "@opentelemetry/api": "^1.9.0",
25
30
  "@orpc/contract": "2.0.0-beta.20",
26
31
  "@orpc/experimental-effect": "2.0.0-beta.20",
27
32
  "@orpc/server": "2.0.0-beta.20",
28
- "@habitat-ai/typebox-adapter": "0.1.0",
33
+ "@habitat-ai/typebox-adapter": "0.1.1",
29
34
  "effect": "4.0.0-beta.101",
30
35
  "picomatch": "4.0.4",
31
36
  "smol-toml": "1.7.0",