-
Notifications
You must be signed in to change notification settings - Fork 500
Refactor parser import/path helpers to eliminate wasm/native drift and duplicate logic #53895
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
9e78cae
Initial plan
Copilot e73cb24
Refactor parser shared path predicates and import helpers
Copilot aa630fc
Address code-review feedback for parser dedupe refactor
Copilot f89921c
docs(adr): add draft ADR-53895 for wasm/native parser helper consolid…
github-actions[bot] e4cbf40
Merge branch 'main' into copilot/refactor-wasm-build-tag-copies
github-actions[bot] 9fce87a
Address parser import review blockers
Copilot 454e737
Merge remote-tracking branch 'origin/main' into copilot/refactor-wasm…
Copilot 68245a7
Apply formatter after branch refresh
Copilot 95881c6
Merge remote-tracking branch 'origin/main' into copilot/refactor-wasm…
Copilot 47e2baa
Merge remote-tracking branch 'origin/main' into copilot/refactor-wasm…
Copilot ea83106
Merge branch 'main' into copilot/refactor-wasm-build-tag-copies
github-actions[bot] ddc6019
Merge branch 'main' into copilot/refactor-wasm-build-tag-copies
pelikhan c4bb71d
Report maintainer finish pass plan
Copilot ff85759
Merge remote-tracking branch 'origin/main' into copilot/refactor-wasm…
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # ADR-53895: Consolidate Duplicated Wasm/Native Parser Helpers into Build-Tag-Free Files | ||
|
|
||
| **Date**: 2026-08-19 | ||
| **Status**: Draft | ||
| **Deciders**: pelikhan, copilot-swe-agent | ||
|
|
||
| --- | ||
|
|
||
| ### Context | ||
|
|
||
| `pkg/parser` maintained separate implementations of five path-predicate helpers — `isUnderWorkflowsDirectory`, `isCustomAgentFile`, `isRepositoryImport`, `IsWorkflowSpec`, and the path-arithmetic helpers `findGitHubFolder` / `computeIncludeResolveAndSecurityBases` — duplicated across `remote_fetch_wasm.go` (build tag `js || wasm`) and `remote_resolve_path.go` / `remote_workflow_spec.go` (build tag `!js && !wasm`). These copies were not thin platform shims; they contained identical business logic, and they had already drifted: the wasm copy of `isRepositoryImport` rejected any repo name containing a dot (`strings.Contains(repo, ".")`), while the native copy rejected only known data-file extensions (`.md`, `.yaml`, `.yml`, `.json`). As a result, a valid import like `githubnext/gh-aw.dev` was accepted on native builds and silently rejected on wasm. The wasm copy also hardcoded string literals (`".github/workflows/"`, `".github/agents/"`) that the native copy correctly referenced via package constants. The repository already contained the right pattern for this situation: `github_token_env.go` is a build-tag-free file that both `github.go` (native) and `github_wasm.go` (wasm) delegate to for shared env-var logic. | ||
|
|
||
| ### Decision | ||
|
|
||
| We will extract all platform-independent path predicates and path-arithmetic helpers into a new build-tag-free file `pkg/parser/remote_path_predicates.go` (plus `path_section.go` for the `path#section` splitter), standardize on the native `isRepositoryImport` semantics (extension-based rejection, not dot-based), and delete the duplicated implementations from the build-tag-specific files. Only the filesystem-probe step (which genuinely differs: `os.Stat` vs. `VirtualFileExists`) remains in the platform-specific files. | ||
|
|
||
| ### Alternatives Considered | ||
|
|
||
| #### Alternative 1: Keep both copies in sync with comments and documentation | ||
|
|
||
| Add comments in both files and a CONTRIBUTING note reminding developers to update both the wasm and native copy whenever either changes. This requires zero structural change and no risk of behavioral regression. | ||
|
|
||
| Why not chosen: the drift in `isRepositoryImport` demonstrates this approach already failed. Cognitive load on every future contributor, with no enforcement mechanism, means further drift is certain. The behavioral bug would recur. | ||
|
|
||
| #### Alternative 2: Define a platform abstraction interface | ||
|
|
||
| Define a `PathPredicates` interface and have each build target provide an implementation, allowing each platform to override specific predicates with full type safety. This is the more formal Go pattern for build-tag polymorphism. | ||
|
|
||
| Why not chosen: none of the five helpers in question have any platform-specific behavior after the `isRepositoryImport` semantics choice is made. An interface with five methods, two concrete implementations that are byte-identical, and zero intentional divergence adds pure indirection with no benefit. It also increases the surface area for future drift by providing a slot where platform differences *could* be introduced even when they shouldn't be. | ||
|
|
||
| #### Alternative 3: Remove the wasm build target | ||
|
|
||
| Eliminate the wasm build entirely to remove the need for any build-tag split, resolving the drift problem permanently. | ||
|
|
||
| Why not chosen: wasm is a key deployment target for browser-based gh-aw use cases. Removing it is not on the roadmap. | ||
|
|
||
| ### Consequences | ||
|
|
||
| #### Positive | ||
| - Eliminates approximately 120 lines of duplicated code across three files and two build targets. | ||
| - Behavioral divergence between native and wasm for `isRepositoryImport` is fixed; dotted repository names like `githubnext/gh-aw.dev` are now accepted consistently. | ||
| - Constants (`WorkflowsDirSlash`, `AgentsDir`, `GithubDir`) are used in both build targets, so future constant changes propagate to both automatically. | ||
| - Follows an established codebase pattern (`github_token_env.go`) rather than introducing a new one. | ||
|
|
||
| #### Negative | ||
| - The build-tag-free file is exercised by the native test suite only; wasm-specific behavior that relied on the old (more restrictive) `isRepositoryImport` predicate could surface as a behavior change in the wasm build without a dedicated wasm test run. | ||
| - `computeIncludeResolveAndSecurityBases` is now shared and called from both `remote_resolve_path.go` and `remote_fetch_wasm.go`; any future divergence between the two platforms' security-boundary logic must be handled at the call site rather than by forking the function. | ||
|
|
||
| #### Neutral | ||
| - The three byte-identical `path#section` splitters (`splitImportPathAndSection`, `splitIncludePathAndSection`, `stripImportSection`) are replaced by a single `splitPathAndSection` helper, consistently using `strings.Cut` instead of `strings.SplitN`. | ||
| - `extractFrontmatterForTopologicalSort` in `import_topological.go` is replaced by a direct call to `extractFrontmatterForImport`, reducing the number of frontmatter extraction helpers from two to one. | ||
| - `isWorkflowSpec` (the wasm-only alias calling `IsWorkflowSpec`) is deleted; call sites now reference `IsWorkflowSpec` directly. | ||
|
|
||
| --- | ||
|
|
||
| *ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package parser | ||
|
|
||
| import "strings" | ||
|
|
||
| func splitPathAndSection(path string) (string, string) { | ||
| if before, after, ok := strings.Cut(path, "#"); ok { | ||
| return before, after | ||
| } | ||
| return path, "" | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.