@fulmenhq/tsfulmen 0.1.8 → 0.1.9

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +241 -4
  3. package/config/crucible-ts/devsecops/lorage-central/activity/v1.0.0/defaults.yaml +19 -0
  4. package/config/crucible-ts/devsecops/lorage-central/credentials/v1.0.0/defaults.yaml +21 -0
  5. package/config/crucible-ts/devsecops/lorage-central/policy/v1.0.0/defaults.yaml +36 -0
  6. package/config/crucible-ts/devsecops/lorage-central/recipe/v1.0.0/defaults.yaml +61 -0
  7. package/config/crucible-ts/devsecops/lorage-central/runbooks/v1.0.0/defaults.yaml +50 -0
  8. package/config/crucible-ts/devsecops/lorage-central/tenant/v1.0.0/defaults.yaml +28 -0
  9. package/config/crucible-ts/devsecops/secrets/v1.0.0/defaults.yaml +198 -0
  10. package/config/crucible-ts/library/fulpack/fixtures/README.md +157 -0
  11. package/config/crucible-ts/library/fulpack/fixtures/basic.tar +0 -0
  12. package/config/crucible-ts/library/fulpack/fixtures/basic.tar.gz +0 -0
  13. package/config/crucible-ts/library/fulpack/fixtures/basic.tar.gz.txt +19 -0
  14. package/config/crucible-ts/library/fulpack/fixtures/basic.tar.txt +54 -0
  15. package/config/crucible-ts/library/fulpack/fixtures/nested.zip +0 -0
  16. package/config/crucible-ts/library/fulpack/fixtures/nested.zip.txt +24 -0
  17. package/config/crucible-ts/library/fulpack/fixtures/pathological.tar.gz +0 -0
  18. package/config/crucible-ts/library/fulpack/fixtures/pathological.tar.gz.txt +49 -0
  19. package/config/crucible-ts/taxonomy/devsecops/auth-methods.yaml +34 -0
  20. package/config/crucible-ts/taxonomy/devsecops/geo.yaml +54 -0
  21. package/config/crucible-ts/taxonomy/devsecops/infra-phases.yaml +43 -0
  22. package/config/crucible-ts/taxonomy/devsecops/infra-providers.yaml +97 -0
  23. package/config/crucible-ts/taxonomy/devsecops/modules/v1.0.0/modules.yaml +46 -0
  24. package/config/crucible-ts/taxonomy/library/foundry-catalogs/v1.0.0/catalogs.yaml +55 -0
  25. package/config/crucible-ts/taxonomy/library/platform-modules/v1.0.0/modules.yaml +591 -0
  26. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  27. package/config/crucible-ts/taxonomy/repository-categories.yaml +53 -45
  28. package/dist/appidentity/index.d.ts +2 -2
  29. package/dist/appidentity/index.js.map +1 -1
  30. package/dist/config/index.d.ts +2 -2
  31. package/dist/config/index.js.map +1 -1
  32. package/dist/crucible/index.d.ts +3 -3
  33. package/dist/crucible/index.js.map +1 -1
  34. package/dist/docscribe/index.d.ts +1 -1
  35. package/dist/docscribe/index.js.map +1 -1
  36. package/dist/errors/index.d.ts +1 -1
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/foundry/index.d.ts +14 -14
  39. package/dist/foundry/index.js.map +1 -1
  40. package/dist/foundry/similarity/index.d.ts +2 -2
  41. package/dist/foundry/similarity/index.js.map +1 -1
  42. package/dist/fulhash/index.js.map +1 -1
  43. package/dist/fulpack/index.d.ts +324 -0
  44. package/dist/fulpack/index.js +1505 -0
  45. package/dist/fulpack/index.js.map +1 -0
  46. package/dist/index.d.ts +3 -2
  47. package/dist/index.js +1508 -10
  48. package/dist/index.js.map +1 -1
  49. package/dist/logging/index.js.map +1 -1
  50. package/dist/pathfinder/index.d.ts +178 -5
  51. package/dist/pathfinder/index.js +189 -18
  52. package/dist/pathfinder/index.js.map +1 -1
  53. package/dist/{registry-BoDv4iHO.d.ts → registry-n88udrCm.d.ts} +2 -2
  54. package/dist/schema/index.d.ts +3 -3
  55. package/dist/schema/index.js.map +1 -1
  56. package/dist/{suggest-CLqjLZ5L.d.ts → suggest-Cv7SVQRu.d.ts} +2 -2
  57. package/dist/telemetry/index.d.ts +3 -3
  58. package/dist/telemetry/index.js.map +1 -1
  59. package/dist/{types-B_WtvQbS.d.ts → types-BJswWpQC.d.ts} +7 -7
  60. package/package.json +10 -1
  61. package/schemas/crucible-ts/devsecops/lorage-central/activity/v1.0.0/README.md +104 -0
  62. package/schemas/crucible-ts/devsecops/lorage-central/activity/v1.0.0/activity.schema.json +118 -0
  63. package/schemas/crucible-ts/devsecops/lorage-central/credentials/v1.0.0/README.md +100 -0
  64. package/schemas/crucible-ts/devsecops/lorage-central/credentials/v1.0.0/credentials.schema.json +123 -0
  65. package/schemas/crucible-ts/devsecops/lorage-central/policy/v1.0.0/README.md +112 -0
  66. package/schemas/crucible-ts/devsecops/lorage-central/policy/v1.0.0/policy.schema.json +197 -0
  67. package/schemas/crucible-ts/devsecops/lorage-central/recipe/v1.0.0/README.md +203 -0
  68. package/schemas/crucible-ts/devsecops/lorage-central/recipe/v1.0.0/recipe.schema.json +353 -0
  69. package/schemas/crucible-ts/devsecops/lorage-central/runbooks/v1.0.0/README.md +280 -0
  70. package/schemas/crucible-ts/devsecops/lorage-central/runbooks/v1.0.0/runbook.schema.json +216 -0
  71. package/schemas/crucible-ts/devsecops/lorage-central/tenant/v1.0.0/README.md +84 -0
  72. package/schemas/crucible-ts/devsecops/lorage-central/tenant/v1.0.0/tenant.schema.json +131 -0
  73. package/schemas/crucible-ts/devsecops/secrets/v1.0.0/secrets.schema.json +250 -0
  74. package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +90 -0
  75. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-entry.schema.json +61 -0
  76. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-info.schema.json +75 -0
  77. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-manifest.schema.json +112 -0
  78. package/schemas/crucible-ts/library/fulpack/v1.0.0/create-options.schema.json +53 -0
  79. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-options.schema.json +49 -0
  80. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-result.schema.json +54 -0
  81. package/schemas/crucible-ts/library/fulpack/v1.0.0/scan-options.schema.json +42 -0
  82. package/schemas/crucible-ts/library/fulpack/v1.0.0/validation-result.schema.json +58 -0
  83. package/schemas/crucible-ts/observability/logging/v1.0.0/logger-config.schema.json +1 -30
  84. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/README.md +47 -0
  85. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-key.schema.json +16 -0
  86. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-metadata.schema.json +49 -0
  87. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/README.md +63 -0
  88. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-key.schema.json +31 -0
  89. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-metadata.schema.json +104 -0
  90. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/README.md +48 -0
  91. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-key.schema.json +17 -0
  92. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-metadata.schema.json +53 -0
  93. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/README.md +73 -0
  94. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-key.schema.json +18 -0
  95. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-metadata.schema.json +77 -0
  96. package/schemas/crucible-ts/taxonomy/devsecops/modules/v1.0.0/devsecops-module-entry.schema.json +117 -0
  97. package/schemas/crucible-ts/taxonomy/library/fulencode/detection-confidence/v1.0.0/levels.schema.json +253 -0
  98. package/schemas/crucible-ts/taxonomy/library/fulencode/detection-confidence/v1.0.0/levels.yaml +167 -0
  99. package/schemas/crucible-ts/taxonomy/library/fulencode/encoding-families/v1.0.0/families.schema.json +184 -0
  100. package/schemas/crucible-ts/taxonomy/library/fulencode/encoding-families/v1.0.0/families.yaml +142 -0
  101. package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.schema.json +253 -0
  102. package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.yaml +173 -0
  103. package/schemas/crucible-ts/taxonomy/library/fulpack/archive-formats/v1.0.0/formats.yaml +86 -0
  104. package/schemas/crucible-ts/taxonomy/library/fulpack/entry-types/v1.0.0/types.yaml +18 -0
  105. package/schemas/crucible-ts/taxonomy/library/fulpack/operations/v1.0.0/operations.yaml +36 -0
  106. package/schemas/crucible-ts/taxonomy/library/modules/v1.0.0/README.md +86 -0
  107. package/schemas/crucible-ts/taxonomy/library/modules/v1.0.0/module-entry.schema.json +408 -0
  108. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-key.schema.json +1 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - **Fulpack Module** (`@fulmenhq/tsfulmen/fulpack`) - Security-first archive operations for TAR, TAR.GZ, ZIP, and GZIP formats
13
+ - **Five Canonical Operations**:
14
+ - `create()` - Create archives from files/directories with configurable compression
15
+ - `extract()` - Extract archives with comprehensive security checks
16
+ - `scan()` - List archive contents without extraction (Pathfinder integration backend)
17
+ - `verify()` - Validate archive integrity and security before extraction
18
+ - `info()` - Get quick archive metadata (format, size, compression ratio)
19
+ - **Security-First Design**:
20
+ - Path traversal protection (rejects `../` and absolute paths)
21
+ - Decompression bomb detection (size/ratio/entry count limits)
22
+ - Symlink safety validation (prevents directory escapes)
23
+ - Checksum verification via fulhash integration (SHA-256, xxh3-128)
24
+ - **Four Archive Formats**:
25
+ - TAR (uncompressed) - Maximum speed for pre-compressed data
26
+ - TAR.GZ (gzip) - General purpose with best compatibility
27
+ - ZIP (deflate) - Windows compatibility and random access
28
+ - GZIP - Single file compression
29
+ - **Pathfinder Integration**: `scan()` serves as backend for archive discovery
30
+ - **Comprehensive Documentation**: Full API reference, security guide, format selection guide, and usage examples
31
+ - **Test Coverage**: 20 tests covering all operations and security checks
32
+ - **Error Handling**: Structured `FulpackOperationError` with operation context and security violation details
33
+
34
+ - **Pathfinder Repository Root Discovery** (`findRepositoryRoot`) - Secure upward traversal to find repository markers
35
+ - **Security-First Design**:
36
+ - Boundary enforcement (home directory/explicit/filesystem root)
37
+ - Max depth limiting (default 10 levels)
38
+ - Symlink loop detection (opt-in with `followSymlinks=true`)
39
+ - Path constraint validation for workspace boundaries
40
+ - Cross-platform support (POSIX root, Windows drives, UNC paths)
41
+ - **Predefined Marker Sets**: GitMarkers, NodeMarkers, PythonMarkers, GoModMarkers, MonorepoMarkers
42
+ - **Flexible Search**: Stop at first marker (default) or find deepest (monorepo root)
43
+ - **Helper Functions**: `withMaxDepth`, `withBoundary`, `withStopAtFirst`, `withConstraint`, `withFollowSymlinks`
44
+ - **Comprehensive Errors**: Structured errors with codes (REPOSITORY_NOT_FOUND, INVALID_BOUNDARY, TRAVERSAL_LOOP, etc.)
45
+ - **Test Coverage**: 26 tests covering security, boundary enforcement, and cross-platform behavior
46
+ - **Complete Documentation**: Full pathfinder README with API reference, safe usage patterns, and migration guide
47
+
10
48
  ---
11
49
 
12
50
  ## [0.1.8] - 2025-11-08
package/README.md CHANGED
@@ -9,10 +9,10 @@ TypeScript Fulmen helper library for enterprise-scale development.
9
9
  ## Status
10
10
 
11
11
  **Lifecycle Phase:** `alpha` (see [`LIFECYCLE_PHASE`](LIFECYCLE_PHASE))
12
- **Development Status:** ✅ v0.1.5 - Signal handling, app identity, and FulHash optimization
13
- **Test Coverage:** 1465 tests passing (100% pass rate, 1481 total)
12
+ **Development Status:** ✅ v0.1.9 - Fulpack archives, pathfinder repository root discovery
13
+ **Test Coverage:** 1638 tests passing (100% pass rate)
14
14
 
15
- TSFulmen v0.1.5 adds cross-platform signal handling with graceful shutdown patterns, complete application identity module, and 22x FulHash performance improvement. See [TSFulmen Overview](docs/tsfulmen_overview.md) for roadmap.
15
+ TSFulmen v0.1.9 adds security-first archive operations (fulpack) for TAR/TAR.GZ/ZIP/GZIP formats and repository root discovery (pathfinder) with boundary enforcement. See [TSFulmen Overview](docs/tsfulmen_overview.md) for roadmap.
16
16
 
17
17
  ## Features
18
18
 
@@ -20,6 +20,7 @@ TSFulmen v0.1.5 adds cross-platform signal handling with graceful shutdown patte
20
20
  - ✅ **Telemetry & Metrics** - Counter/gauge/histogram with OTLP export (85 tests)
21
21
  - ✅ **Telemetry Instrumentation** - Metrics in config, schema, crucible modules (24 tests)
22
22
  - ✅ **FulHash** - Fast hashing with XXH3-128 and SHA-256, 22x faster small inputs (157 tests)
23
+ - ✅ **Fulpack** - Archive operations (TAR, TAR.GZ, ZIP, GZIP) with security-first design (20 tests)
23
24
  - ✅ **Progressive Logging** - Policy enforcement with Pino profiles (83 tests)
24
25
  - ✅ **Crucible Shim** - Typed access to synced schemas, docs, and config defaults (96 tests)
25
26
  - ✅ **DocScribe** - Document processing with frontmatter parsing (50+ tests)
@@ -29,7 +30,7 @@ TSFulmen v0.1.5 adds cross-platform signal handling with graceful shutdown patte
29
30
  - ✅ **Exit Codes** - Standardized process exit codes with simplified modes and platform detection (34 tests)
30
31
  - ✅ **Signal Handling** - Cross-platform signal handling with graceful shutdown and Windows fallback (180 tests)
31
32
  - ✅ **Application Identity** - .fulmen/app.yaml discovery with caching and validation (93 tests)
32
- - ✅ **Pathfinder** - Filesystem traversal with checksums, ignore files, and observability (44 tests)
33
+ - ✅ **Pathfinder** - Filesystem traversal, repository root discovery with security boundaries, checksums, and observability (70 tests)
33
34
  - 🚧 **Three-Layer Config Loading** - Defaults → User → BYOC (planned v0.2.x)
34
35
 
35
36
  ## Installation
@@ -108,6 +109,8 @@ src/
108
109
  ├── crucible/ # 🚧 Crucible SSOT shim
109
110
  ├── errors/ # ✅ Error handling & propagation
110
111
  ├── foundry/ # ✅ Pattern catalogs, HTTP statuses, MIME detection
112
+ ├── fulhash/ # ✅ Fast hashing with XXH3-128 and SHA-256
113
+ ├── fulpack/ # ✅ Archive operations (TAR, TAR.GZ, ZIP, GZIP)
111
114
  ├── logging/ # ✅ Progressive logging with policy enforcement
112
115
  ├── pathfinder/ # ✅ Filesystem traversal with checksums and observability
113
116
  ├── schema/ # ✅ Schema validation (AJV + CLI)
@@ -515,6 +518,240 @@ const type = await detectMimeType(buffer, {
515
518
  });
516
519
  ```
517
520
 
521
+ ### Fulpack - Archive Operations
522
+
523
+ Secure archive creation, extraction, and inspection with security-first design for TAR, TAR.GZ, ZIP, and GZIP formats.
524
+
525
+ **Features:**
526
+
527
+ - Five canonical operations: `create()`, `extract()`, `scan()`, `verify()`, `info()`
528
+ - Four archive formats: TAR (uncompressed), TAR.GZ (gzip), ZIP (deflate), GZIP (single file)
529
+ - Security-first design: path traversal protection, decompression bomb detection, symlink safety validation
530
+ - Checksum verification via fulhash integration (SHA-256, xxh3-128)
531
+ - Pathfinder integration: `scan()` backend for archive discovery
532
+ - Streaming architecture for memory-efficient operations
533
+
534
+ **Basic Usage:**
535
+
536
+ ```typescript
537
+ import {
538
+ create,
539
+ extract,
540
+ scan,
541
+ verify,
542
+ info,
543
+ ArchiveFormat,
544
+ } from "@fulmenhq/tsfulmen/fulpack";
545
+
546
+ // Create TAR.GZ archive
547
+ const archiveInfo = await create(
548
+ "./src", // Source directory
549
+ "./dist/app.tar.gz", // Output archive
550
+ ArchiveFormat.TAR_GZ, // Format
551
+ { compression_level: 9 }, // Options
552
+ );
553
+
554
+ // Extract archive with security checks
555
+ const result = await extract(
556
+ "./dist/app.tar.gz", // Archive path
557
+ "./output", // Destination
558
+ { overwrite: "skip" }, // Skip existing files
559
+ );
560
+
561
+ console.log(
562
+ `Extracted ${result.extracted_count} files, skipped ${result.skipped_count}`,
563
+ );
564
+ ```
565
+
566
+ **Scan Archives (Pathfinder Integration):**
567
+
568
+ ```typescript
569
+ // Scan archive contents without extraction
570
+ const entries = await scan("./data.tar.gz");
571
+
572
+ // Filter entries using standard JavaScript
573
+ const csvFiles = entries.filter(
574
+ (e) => e.type === "file" && e.path.endsWith(".csv"),
575
+ );
576
+ console.log(`Found ${csvFiles.length} CSV files`);
577
+
578
+ // Check for specific files
579
+ const hasConfig = entries.some((e) => e.path === "config/app.json");
580
+
581
+ // Get total uncompressed size
582
+ const totalSize = entries.reduce((sum, e) => sum + e.size, 0);
583
+ console.log(`Total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
584
+ ```
585
+
586
+ **Security Validation:**
587
+
588
+ ```typescript
589
+ // Verify archive integrity before extraction
590
+ const validation = await verify("./untrusted.tar.gz");
591
+
592
+ if (!validation.valid) {
593
+ console.error("Archive validation failed:");
594
+ validation.errors.forEach((err) =>
595
+ console.error(` - ${err.code}: ${err.message}`),
596
+ );
597
+ process.exit(1);
598
+ }
599
+
600
+ // Check security validations performed
601
+ console.log("Security checks:", validation.checks_performed.join(", "));
602
+ // Output: structure_valid, no_path_traversal, symlinks_safe, no_decompression_bomb
603
+ ```
604
+
605
+ **Archive Metadata:**
606
+
607
+ ```typescript
608
+ // Get quick metadata without extraction
609
+ const metadata = await info("./backup.tar.gz");
610
+
611
+ console.log(`Format: ${metadata.format}`);
612
+ console.log(`Entries: ${metadata.entry_count}`);
613
+ console.log(
614
+ `Compressed: ${(metadata.compressed_size / 1024 / 1024).toFixed(2)} MB`,
615
+ );
616
+ console.log(
617
+ `Uncompressed: ${(metadata.total_size / 1024 / 1024).toFixed(2)} MB`,
618
+ );
619
+ console.log(`Ratio: ${metadata.compression_ratio.toFixed(2)}:1`);
620
+ ```
621
+
622
+ **Format Selection:**
623
+
624
+ ```typescript
625
+ // TAR (uncompressed) - Fastest for pre-compressed data
626
+ await create("./images", "./backup.tar", ArchiveFormat.TAR);
627
+
628
+ // TAR.GZ - General purpose, best compatibility
629
+ await create("./src", "./release.tar.gz", ArchiveFormat.TAR_GZ, {
630
+ compression_level: 9,
631
+ exclude_patterns: ["**/*.test.ts", "**/node_modules/**"],
632
+ });
633
+
634
+ // ZIP - Windows compatibility, random access
635
+ await create(["./config", "./scripts"], "./deploy.zip", ArchiveFormat.ZIP);
636
+
637
+ // GZIP - Single file compression
638
+ await create("./large-data.csv", "./large-data.csv.gz", ArchiveFormat.GZIP);
639
+ ```
640
+
641
+ ### Pathfinder - Repository Root Discovery
642
+
643
+ Find repository markers (`.git`, `package.json`, etc.) by walking up the directory tree with security-first design, boundary enforcement, and comprehensive error handling.
644
+
645
+ **Features:**
646
+
647
+ - Security-first design with boundary enforcement (home directory/explicit/filesystem root ceilings)
648
+ - Max depth limiting (default 10 levels) to prevent excessive traversal
649
+ - Symlink loop detection with opt-in following
650
+ - Path constraint validation for workspace boundaries
651
+ - Cross-platform support (POSIX root, Windows drives, UNC paths)
652
+ - Predefined marker sets for common ecosystems (Git, Node, Python, Go, Monorepo)
653
+ - Structured errors with context for debugging
654
+
655
+ **Basic Usage:**
656
+
657
+ ```typescript
658
+ import {
659
+ findRepositoryRoot,
660
+ GitMarkers,
661
+ NodeMarkers,
662
+ } from "@fulmenhq/tsfulmen/pathfinder";
663
+
664
+ // Find Git repository root from current directory
665
+ const gitRoot = await findRepositoryRoot(process.cwd(), GitMarkers);
666
+ console.log(`Git root: ${gitRoot}`);
667
+
668
+ // Find Node.js project root
669
+ const nodeRoot = await findRepositoryRoot("./src/components", NodeMarkers);
670
+ console.log(`Node root: ${nodeRoot}`);
671
+ ```
672
+
673
+ **Predefined Marker Sets:**
674
+
675
+ ```typescript
676
+ import {
677
+ GitMarkers, // [".git"]
678
+ NodeMarkers, // ["package.json", "package-lock.json"]
679
+ PythonMarkers, // ["pyproject.toml", "setup.py", "requirements.txt", "Pipfile"]
680
+ GoModMarkers, // ["go.mod"]
681
+ MonorepoMarkers, // ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"]
682
+ } from "@fulmenhq/tsfulmen/pathfinder";
683
+ ```
684
+
685
+ **Security Boundaries:**
686
+
687
+ ```typescript
688
+ import {
689
+ ConstraintType,
690
+ EnforcementLevel,
691
+ } from "@fulmenhq/tsfulmen/pathfinder";
692
+
693
+ // Secure search within project boundary
694
+ const root = await findRepositoryRoot("./src/components", GitMarkers, {
695
+ boundary: "/home/user/projects/myapp", // Don't search above project
696
+ constraint: {
697
+ root: "/home/user/projects", // Enforce workspace constraint
698
+ type: ConstraintType.WORKSPACE,
699
+ enforcementLevel: EnforcementLevel.STRICT,
700
+ },
701
+ });
702
+ ```
703
+
704
+ **Monorepo Support:**
705
+
706
+ ```typescript
707
+ // Find deepest marker (closest to filesystem root) for monorepo roots
708
+ // Directory: /monorepo/.git and /monorepo/packages/app/.git
709
+
710
+ // stopAtFirst=true (default) - finds /monorepo/packages/app
711
+ const packageRoot = await findRepositoryRoot(
712
+ "/monorepo/packages/app/src/index.ts",
713
+ GitMarkers,
714
+ );
715
+
716
+ // stopAtFirst=false - finds /monorepo (deepest/monorepo root)
717
+ const monorepoRoot = await findRepositoryRoot(
718
+ "/monorepo/packages/app/src/index.ts",
719
+ GitMarkers,
720
+ { stopAtFirst: false },
721
+ );
722
+ ```
723
+
724
+ **Error Handling:**
725
+
726
+ ```typescript
727
+ import { PathfinderErrorCode } from "@fulmenhq/tsfulmen/pathfinder";
728
+
729
+ try {
730
+ const root = await findRepositoryRoot("./src", GitMarkers);
731
+ console.log(`Found: ${root}`);
732
+ } catch (error) {
733
+ if (error.data?.code === PathfinderErrorCode.REPOSITORY_NOT_FOUND) {
734
+ console.error("No repository marker found");
735
+ console.error(`Searched from: ${error.data.context.startPath}`);
736
+ console.error(`Max depth: ${error.data.context.maxDepth}`);
737
+ } else if (error.data?.code === PathfinderErrorCode.TRAVERSAL_LOOP) {
738
+ console.error("Cyclic symlink detected:", error.data.context);
739
+ } else {
740
+ throw error; // Re-throw unexpected errors
741
+ }
742
+ }
743
+ ```
744
+
745
+ **Default Behavior:**
746
+
747
+ - **`maxDepth`**: `10` - Prevents excessive traversal
748
+ - **`boundary`**: User home directory (if start path under home), otherwise filesystem root
749
+ - **`stopAtFirst`**: `true` - Returns first marker found (closest to start path)
750
+ - **`followSymlinks`**: `false` - Security: symlinks not followed by default
751
+ - **`constraint`**: `undefined` - No additional path constraints
752
+
753
+ See [Pathfinder README](src/pathfinder/README.md) for complete API documentation.
754
+
518
755
  ### Pathfinder - Filesystem Discovery
519
756
 
520
757
  Enterprise filesystem traversal with pattern matching, ignore files, optional checksums, and comprehensive observability.
@@ -0,0 +1,19 @@
1
+ # config/devsecops/lorage-central/activity/v1.0.0/defaults.yaml
2
+ # L'Orage Central Activity Record Defaults
3
+ # Description: Default audit config (e.g., event templates; emitted auto).
4
+ # Rationale: Structured logging defaults; retain per policy.audit.
5
+ # Version: v1.0.0 (Ties to schema; integrates gofulmen).
6
+ # Example Event Template (auto-populated in REPL)
7
+ eventTemplate:
8
+ eventType: unlock # From enum
9
+ outcome: success
10
+ metadata:
11
+ sessionId: "sess-default-001"
12
+ userId: "user-anon-123"
13
+ duration: "5s"
14
+ details: {method: totp}
15
+ backend: # Refs policy.audit
16
+ level: structured
17
+ retain: 30d
18
+ # Usage: REPL emits: {id: evt-default-unlock-001, timestamp: now, tenant: tnt-uuid-123-prod-us, ...}
19
+ # Stored in audit backend (e.g., Turso table); no defaults for id/timestamp (runtime).
@@ -0,0 +1,21 @@
1
+ # config/devsecops/lorage-central/credentials/v1.0.0/defaults.yaml
2
+ # L'Orage Central Root Credentials Defaults
3
+ # Description: Default metadata for root creds (e.g., bootstrap key; no values—refs only).
4
+ # Rationale: Secure defaults (1y expiry); used in seeding/actions.
5
+ # Version: v1.0.0 (Ties to schema; backend from policy).
6
+ id: default-bootstrap-key
7
+ tenant: tnt-uuid-123-prod-us # From registry
8
+ type: gpg-key
9
+ ref: "gpg://keyring/default-bootstrap" # Opaque; decrypted at runtime
10
+ metadata:
11
+ created: "2025-11-09T12:00:00Z"
12
+ expires: "2026-11-09T12:00:00Z" # 1y default
13
+ purpose: tenant-bootstrap
14
+ rotation:
15
+ interval: 365d
16
+ method: manual
17
+ backend: # Refs policy.isolation.store
18
+ type: gpg-file
19
+ enc: true
20
+ # Usage: In recipe.actions or seeding: ref this for bootstrap; REPL checks expiry.
21
+ # Example: For Turso, type: turso-root, ref: "turso://root-auth".
@@ -0,0 +1,36 @@
1
+ # config/devsecops/lorage-central/policy/v1.0.0/defaults.yaml
2
+ # L'Orage Central Tenant Policy Defaults
3
+ # Description: Default policy for new tenants (loaded via three-layer config; overrides in .fulmen/lorage.yaml).
4
+ # Rationale: Secure MVP defaults (short TTL, MFA required, Turso backend); confidential example (obscure publicId).
5
+ # Version: v1.0.0 (Ties to schema; auto-applies dataSensitivity guards from registry).
6
+ tenant: tnt-uuid-123-prod-us # Obscure publicId from registry (confidential=true; no client exposure)
7
+ session:
8
+ ttl:
9
+ default: 15m # Force re-unlock per session
10
+ ops:
11
+ deploy: 1h
12
+ query: 5m
13
+ seed: 30m
14
+ maxConcurrent: 1 # Strict isolation
15
+ mfa:
16
+ required: true # Auto-true if registry.dataSensitivity.pii=true
17
+ methods: [totp, webauthn] # From auth-methods taxonomy
18
+ fallback: cli-prompt
19
+ isolation:
20
+ store:
21
+ type: turso # HA default
22
+ conn:
23
+ url: "turso://default-db" # Placeholder; ref root-credentials
24
+ auth: {ref: "gpg://keyring/default-bootstrap"}
25
+ enc: false # Enable for cloud-free
26
+ crossAccess: false
27
+ geoRestrictions: [eu-west-1] # From registry.geo (e.g., EU for GDPR)
28
+ cloudRestrictions: [aws, doc] # From registry.cloud
29
+ dataSensitivityGuards:
30
+ pii: false # Auto-from registry; triggers mfa/geo if true
31
+ phi: false # Triggers enc/audit if true
32
+ audit:
33
+ level: structured # gofulmen integration
34
+ retain: 30d
35
+ # Usage: REPL loads defaults + overrides; validates against schema/registry.
36
+ # Example Override: For PHI tenant, set dataSensitivityGuards.phi: true → auto-enc=true.
@@ -0,0 +1,61 @@
1
+ # config/devsecops/lorage-central/recipe/v1.0.0/defaults.yaml
2
+ # L'Orage Central Recipe Defaults
3
+ # Description: Default recipe config (e.g., for Mattermost MVP); loaded via three-layer.
4
+ # Rationale: Declarative base (components/phases); procedural actions for bootstrap.
5
+ # Version: v1.0.0 (Ties to schema; refs taxonomies for provider/backend/phase).
6
+ name: mattermost-stack # Slug-safe
7
+ type: deploy
8
+ target:
9
+ provider: doc # From infra-providers
10
+ region: nyc3
11
+ backend: opentofu # From toolchains
12
+ components:
13
+ - name: postgres
14
+ image: postgres:15
15
+ phase: storage # From infra-phases (order 3)
16
+ ports: [5432]
17
+ env:
18
+ POSTGRES_DB: mattermost
19
+ secrets:
20
+ - ref: "gpg://keyring/acme/db-pass"
21
+ injectAs: POSTGRES_PASSWORD
22
+ dependsOn: [] # No deps for base DB
23
+ module: db-postgres # Tofu module
24
+ - name: mattermost
25
+ image: mattermost/mattermost-team:latest
26
+ phase: compute # Order 4
27
+ ports: [8065]
28
+ env:
29
+ MM_POSTGRES_URL: "postgres://user:pass@localhost:5432/mattermost"
30
+ secrets:
31
+ - ref: "gpg://keyring/acme/mm-secret"
32
+ injectAs: MM_SECRET
33
+ dependsOn: [postgres]
34
+ module: app-mattermost
35
+ actions:
36
+ - type: bootstrap
37
+ phase: bootstrap # Order 0; procedural for key gen
38
+ cmd: "gpg --gen-key --batch acme-bootstrap" # Example script
39
+ dependsOn: []
40
+ - type: script
41
+ phase: network # Order 2
42
+ cmd: "doctl compute vpc create --name acme-vpc" # SDK wrapper for VPC
43
+ dependsOn: [bootstrap]
44
+ secrets:
45
+ backend: gpg-keyring # Refs policy.isolation.store
46
+ globalRefs:
47
+ - ref: "turso://shared-network-key"
48
+ validate:
49
+ - type: health
50
+ endpoint: "http://localhost:8065/health"
51
+ - type: connect
52
+ endpoint: "postgres://localhost:5432/mattermost"
53
+ diff: # For seed type
54
+ from: v1-0
55
+ to: v1-1
56
+ changes:
57
+ - op: add
58
+ path: /entries/mm-secret
59
+ value: {ref: "gpg://keyring/acme/mm-secret"}
60
+ # Usage: REPL: lorage deploy --recipe mattermost-stack (loads defaults + overrides; topo-sorts phases/actions).
61
+ # Example: For Open edX, add k3s module in compute phase, network action for LB.
@@ -0,0 +1,50 @@
1
+ # config/devsecops/lorage-central/runbooks/v1.0.0/defaults.yaml
2
+ # L'Orage Central Runbook Defaults
3
+ # Description: Default runbook config (e.g., global-network prototype); loaded via three-layer.
4
+ # Rationale: Serializes Markdown prototypes (e.g., from .plans/research/); executable in REPL.
5
+ # Version: v1.0.0 (Ties to schema; refs phases/recipe for steps).
6
+ id: global-network # Slug-safe
7
+ title: Global Enterprise Network Setup
8
+ tenantScope: [all] # Or specific publicIds
9
+ description: >-
10
+ Beginnings of the Runbook: Global Enterprise Picture with Tenants. Our runbook will live in the IDE... (from prototypes).
11
+ phases:
12
+ - id: bootstrap # From infra-phases
13
+ title: Initial Setup
14
+ description: "Core Components: Provision monitoring first."
15
+ steps:
16
+ - id: vaultwarden-init
17
+ type: script
18
+ content: "docker run -d --name vaultwarden vaultwarden/server:latest" # Bootstrap secrets
19
+ dependsOn: []
20
+ parallel: false
21
+ - id: prometheus-setup
22
+ type: action
23
+ ref: prometheus-stack # Ref recipe
24
+ dependsOn: [vaultwarden-init]
25
+ - id: network # Order 2
26
+ title: Networking Backbone
27
+ description: "Zero-trust backbone (Cloudflare Gateway); VPC peering for hybrids."
28
+ steps:
29
+ - id: tenant-table
30
+ type: table
31
+ content: |
32
+ | Tenant | Type | Focus | Clouds (Priority) | Secrets Scope | Initial Infra Needs |
33
+ |--------|------|-------|-------------------|---------------|---------------------|
34
+ | fulmenhq | Ecosystem | Tonnerre templates | AWS/GCP (core), Cloudflare (edge), Hetzner/DO (cost-opt) | IaC vars, SDK keys | OpenTofu state backend (S3), CI/CD pipelines |
35
+ | 3 Leaps Sponsored | Internal | Sponsored OSS | Cloudflare (Workers/DNS), Azure (AI), Hetzner (compute) | API tokens, DB creds | Worker deployments, basic storage |
36
+ | 3 Leaps Commercial | External | Client-specific | Client-dictated (AWS/Azure/GCP) | Isolated vaults | Hybrid connectivity, compliance-heavy |
37
+ dependsOn: []
38
+ parallel: true # Table review parallel with setup
39
+ - id: vpc-peering-setup
40
+ type: script
41
+ content: "doctl compute vpc create --name global-vpc" # Create VPC for hybrid peering
42
+ dependsOn: [tenant-table]
43
+ validate:
44
+ type: custom
45
+ script: "check-vpc-connectivity.sh"
46
+ audit:
47
+ backend: postgres
48
+ retention: 30
49
+ # Usage: REPL: lorage runbook global-network --phase network (executes steps, audits).
50
+ # Example: From prototypes—serialize Markdown tables/scripts; future: Conditional for tenant.geo.
@@ -0,0 +1,28 @@
1
+ # config/devsecops/lorage-central/tenant/v1.0.0/defaults.yaml
2
+ # L'Orage Central Tenant Registry Defaults
3
+ # Description: Default registry for new clients/tenants (loaded via three-layer; e.g., bootstrap new client).
4
+ # Rationale: Confidential example (obscure publicIds); multi-tenant per client (prod/dev).
5
+ # Version: v1.0.0 (Ties to schema; geo/cloud from taxonomies).
6
+ client:
7
+ id: default-client-internal
8
+ name: Default Client # Confidential; not exposed
9
+ confidential: true # Obscure publicIds (UUID-based)
10
+ tenants:
11
+ - publicId: tnt-uuid-123-prod-us # Globally unique/obscure
12
+ purpose: production-mattermost
13
+ geo: [na] # From geo-regions (expands to us/ca)
14
+ cloud: [doc, aws] # From infra-providers
15
+ dataSensitivity:
16
+ pii: false
17
+ phi: false
18
+ other: [] # e.g., [pci-dss]
19
+ - publicId: tnt-uuid-456-dev-eu
20
+ purpose: development-testing
21
+ geo: [eu] # Expands to de/fr/gb/ch (conventions)
22
+ cloud: [gcp]
23
+ dataSensitivity:
24
+ pii: true # Triggers policy guards (mfa/geo)
25
+ phi: false
26
+ globalUniqueness: true # Enforced (UUID for anon)
27
+ # Usage: REPL loads defaults + client overrides; validates publicId uniqueness.
28
+ # Example: For confidential client, generate UUID publicIds; pii=true → policy.mfa.required=true.