Fix overlapping scope roots for nested Codex config paths#3719
Conversation
docs-builder 1.29.0 added extension roots from FindGitRoot for Codex commands. When config.yml lives under environments/internal/, the resolved root is nested inside WorkingDirectoryRoot and ScopedFileSystem rejects the overlapping roots. Normalize extension roots before constructing the scoped filesystem so redundant nested paths are dropped. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
The ProblemThe When a Codex command runs, it calls: FileSystemFactory.ScopeCurrentWorkingDirectory(fs, [Paths.FindGitRoot(config.FullName)]);
Since Now the original
The FixThe PR adds Since only the 2 default roots remain (and the updated guard checks they're specifically For genuinely external extension roots (e.g., detection-rules in a separate checkout), they survive the filter because they're not descendants of any other root: |
Why
|
docs-builder 1.29.0 added extension roots from FindGitRoot for Codex commands. When config.yml lives under environments/internal/, the resolved root is nested inside WorkingDirectoryRoot and ScopedFileSystem rejects the overlapping roots. Normalize extension roots before constructing the scoped filesystem so redundant nested paths are dropped. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
* Emit Mermaid diagrams as external SVG files loaded via img (#3713) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Fix CopyBrandingResources failure during serve in-memory build (#3718) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Fix overlapping scope roots for nested Codex config paths (#3719) docs-builder 1.29.0 added extension roots from FindGitRoot for Codex commands. When config.yml lives under environments/internal/, the resolved root is nested inside WorkingDirectoryRoot and ScopedFileSystem rejects the overlapping roots. Normalize extension roots before constructing the scoped filesystem so redundant nested paths are dropped. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Simplify scope root normalization for nested extension roots (#3720) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Replace pagefind native binary with Pagefind.Net managed library Replace PR #3709's native pagefind binary subprocess approach with the Pagefind.Net and Pagefind.Net.Frontend NuGet packages — pure managed .NET, no native binary, AOT-compatible. The pagefind indexer is now a proper IMarkdownExporter that eagerly indexes each page during ExportAsync (O(1) memory) and flushes the index to disk in FinishExportAsync. It is included in both ExportOptions.Default and ExportOptions.Validation, so it works in isolated builds and docs-builder serve mode automatically. Key changes: - New PagefindMarkdownExporter in Elastic.Markdown/Exporters/Pagefind - New Exporter.Pagefind enum value, registered in both ExporterParsers - Removed native binary pipeline (package-pagefind.mjs, embedded resource, pagefind npm dep, PagefindSearchIndexer subprocess) - Removed static-search feature flag — search is always available for isolated builds and serve mode - Serve mode reads pagefind files from the background build's in-memory filesystem via a route handler - Added .pagefind-net-frontend-version to AllowedHiddenFileNames Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Jan Calanog <jan.calanog@elastic.co>
* Emit Mermaid diagrams as external SVG files loaded via img (#3713) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Fix CopyBrandingResources failure during serve in-memory build (#3718) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Fix overlapping scope roots for nested Codex config paths (#3719) docs-builder 1.29.0 added extension roots from FindGitRoot for Codex commands. When config.yml lives under environments/internal/, the resolved root is nested inside WorkingDirectoryRoot and ScopedFileSystem rejects the overlapping roots. Normalize extension roots before constructing the scoped filesystem so redundant nested paths are dropped. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Simplify scope root normalization for nested extension roots (#3720) Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> * Replace pagefind native binary with Pagefind.Net managed library Replace PR #3709's native pagefind binary subprocess approach with the Pagefind.Net and Pagefind.Net.Frontend NuGet packages — pure managed .NET, no native binary, AOT-compatible. The pagefind indexer is now a proper IMarkdownExporter that eagerly indexes each page during ExportAsync (O(1) memory) and flushes the index to disk in FinishExportAsync. It is included in both ExportOptions.Default and ExportOptions.Validation, so it works in isolated builds and docs-builder serve mode automatically. Key changes: - New PagefindMarkdownExporter in Elastic.Markdown/Exporters/Pagefind - New Exporter.Pagefind enum value, registered in both ExporterParsers - Removed native binary pipeline (package-pagefind.mjs, embedded resource, pagefind npm dep, PagefindSearchIndexer subprocess) - Removed static-search feature flag — search is always available for isolated builds and serve mode - Serve mode reads pagefind files from the background build's in-memory filesystem via a route handler - Added .pagefind-net-frontend-version to AllowedHiddenFileNames Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Jan Calanog <jan.calanog@elastic.co>
Why
docs-builder 1.29.0 scopes Codex commands with
FindGitRoot(config.FullName)as an extension root. For configs underenvironments/internal/config.yml, that root sits insideWorkingDirectoryRoot, andScopedFileSystemthrowsScope roots must be disjoint. This breakscodex-environmentsCI (docs-builder codex clone) on every run since 1.29.0 shipped.What
Normalize extension roots in
FileSystemFactory.ScopeCurrentWorkingDirectorybefore building scoped filesystem options: deduplicate paths and drop roots already covered by an ancestor. Adds regression tests for nested in-repo configs and genuinely external config roots.After merge and release,
codex-environmentsworkflows usingversion: latestshould recover automatically. Until then, that repo can pin docs-builder to1.28.0as a workaround.Made with Cursor