feat(resolve): add runtime fetch schema and ResolveSkillURL (Phase 4 PR 1) - #2104
feat(resolve): add runtime fetch schema and ResolveSkillURL (Phase 4 PR 1)#2104ggallen wants to merge 1 commit into
Conversation
Site previewPreview: https://beeaada0-site.fullsend-ai.workers.dev Commit: |
|
🤖 Finished Review · ✅ Success · Started 12:13 AM UTC · Completed 12:24 AM UTC |
ReviewFindingsMedium
Low
Info
Previous runReviewFindingsHigh
Medium
Low
Info
Previous run (2)ReviewFindingsMedium
Low
Info
Previous run (3)ReviewFindingsMedium
Low
Info
Previous run (4)ReviewFindingsHigh
Medium
Low
Info
Previous run (5)ReviewFindingsMedium
Low
Info
Previous run (6)ReviewFindingsHigh
Medium
Low
Info
Previous run (7)ReviewFindingsLow
Info
Previous run (8)ReviewFindingsLow
Previous run (9)ReviewFindingsMedium
Low
Previous run (10)ReviewFindingsLow
Info
|
dabf824 to
e4ff7ad
Compare
|
🤖 Finished Review · ✅ Success · Started 1:05 AM UTC · Completed 1:16 AM UTC |
e4ff7ad to
0b29673
Compare
|
🤖 Finished Review · ✅ Success · Started 2:04 AM UTC · Completed 2:20 AM UTC |
0b29673 to
752360c
Compare
|
🤖 Finished Review · ✅ Success · Started 3:15 AM UTC · Completed 3:28 AM UTC |
752360c to
e0eac6a
Compare
|
🤖 Finished Review · ✅ Success · Started 11:32 AM UTC · Completed 11:46 AM UTC |
e0eac6a to
9666371
Compare
8ac8d39 to
2f4c858
Compare
|
🤖 Review · Started 3:07 AM UTC |
2f4c858 to
820c2d4
Compare
|
🤖 Finished Review · ✅ Success · Started 3:14 AM UTC · Completed 3:28 AM UTC |
When a GitHub Actions workflow is cancelled (cancel-in-progress), the status comment was left showing "Started" permanently. Two bugs caused this: 1. Go's default SIGINT handler calls os.Exit(2), which skips deferred cleanup. Fix: use signal.NotifyContext so SIGINT/SIGTERM cancel the context and defers run. 2. The root command used Execute() instead of ExecuteContext(), so cmd.Context() returned context.Background() — ctx.Err() was never non-nil and the "cancelled" status path was unreachable. Fix: thread the signal-aware context through ExecuteContext(). 3. The cancelled status path deleted the start comment instead of updating it. Fix: remove the special-case deletion so cancellation goes through the same update-in-place logic as success/failure, showing "⚠️ Cancelled" in the comment. Fixes fullsend-ai#2104 Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
|
Looks like this is including more changes than intended... is that right? It is re-adding files that were deleted for example. Please fix it. |
820c2d4 to
9468768
Compare
E2E tests did not runE2E tests run automatically for org/repo members and collaborators on pull requests. For other contributors, a maintainer must add the See E2E testing guide for details. |
|
🤖 Finished Review · ✅ Success · Started 11:01 AM UTC · Completed 11:17 AM UTC |
| @@ -57,6 +57,8 @@ func TestFullsendRepoFilesExist(t *testing.T) { | |||
| ".github/workflows/review.yml", | |||
There was a problem hiding this comment.
[medium] missing-test-entry
The new composite action .github/actions/mint-token/action.yml is added to the scaffold directory but is not included in the TestFullsendRepoFilesExist expected file list. Only setup-gcp/action.yml and validate-enrollment/action.yml were added.
Suggested fix: Add .github/actions/mint-token/action.yml to the expected slice in TestFullsendRepoFilesExist.
There was a problem hiding this comment.
Fixed — added .github/actions/mint-token/action.yml to the expected file list in TestFullsendRepoFilesExist (413e2cb).
|
|
||
| **Dispatch workflows:** The scaffold `dispatch.yml` (at `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml`) and the repo's `reusable-dispatch.yml` (at `.github/workflows/reusable-dispatch.yml`) share identical routing logic for different installation modes (per-org vs per-repo). When changing the jq payload construction, stage routing, or input/secret threading in one, apply the same change to the other. | ||
|
|
||
| **Forge abstraction:** All git forge operations must go through the `forge.Client` interface in `internal/forge/forge.go`. Do not use `exec.Command("gh", ...)` or direct GitHub API calls outside `internal/forge/github/`. See [AGENTS.md](AGENTS.md#forge-abstraction) for details. |
There was a problem hiding this comment.
[medium] removed-guidance-still-valid
The diff removes the Dispatch workflows paragraph that instructs contributors to keep dispatch.yml and reusable-dispatch.yml in sync. Both files still exist and share routing logic. Removing this guidance without relocating it increases the risk of drift.
Suggested fix: Either keep the paragraph in CLAUDE.md, or move it to a more appropriate location.
There was a problem hiding this comment.
Fixed — restored the dispatch workflows paragraph in CLAUDE.md. It was incorrectly removed during rebase conflict resolution (413e2cb).
| @@ -290,6 +292,12 @@ func (h *Harness) Validate() error { | |||
| if h.ValidationLoop != nil && h.ValidationLoop.Script == "" { | |||
There was a problem hiding this comment.
[low] missing-validation
Validate() does not check whether allow_runtime_fetch: true is accompanied by a non-empty allowed_remote_resources list. ResolveSkillURL has a runtime guard but explicit validation at config load time would give a better error message.
There was a problem hiding this comment.
Acknowledged — ResolveSkillURL checks the allowlist at runtime (line 489), which rejects URLs when allowed_remote_resources is empty. Adding a validation-time check would give a better error message but is lower priority since the runtime guard catches it. Can add in a follow-up if needed.
| // fetch. Like static skill resolution, it uses the forge API to list and fetch | ||
| // the skill directory contents, verifies the tree hash, and caches the result. | ||
| // The audit entry uses FetchType "runtime" to distinguish from static resolution. | ||
| // No transitive resolution — runtime-fetched skills are leaf nodes. |
There was a problem hiding this comment.
[low] error-message-consistency
Error message prefix runtime: differs from existing field-based error prefixes in the same file.
There was a problem hiding this comment.
Fixed — changed all error prefixes in ResolveSkillURL from ad-hoc "runtime: " to field-based "runtime_skill: ", consistent with the field parameter pattern used by resolveURL and resolveSkillDirURL (413e2cb).
…PR 1) Add allow_runtime_fetch and max_runtime_fetches harness fields with validation, and export ResolveSkillURL for single-URL runtime skill resolution with SSRF protection, integrity verification, caching, and "runtime" audit logging. Includes Phase 3/4 implementation plan docs and cross-references from Phase 1/2 plans. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
9468768 to
413e2cb
Compare
|
🤖 Finished Review · ✅ Success · Started 11:28 AM UTC · Completed 11:48 AM UTC |
This is what I get for working late at night. I'm going to close this and open an entirely new PR. Thanks for catching it, @rh-hemartin. |
|
Needs a complete rewrite based on other changes. Closing. |
|
🤖 Finished Retro · ✅ Success · Started 2:21 PM UTC · Completed 2:26 PM UTC |
Retro: PR #2104 — closed without merge after 10 review cyclesWhat happened: PR #2104 ( Token cost: 10 review dispatches on a PR that was ultimately discarded — significant wasted compute. Existing issues that cover most improvement areas:
One new proposal below for escalating scope-tier-mismatch findings to blocking severity when the scope ratio is extreme. Proposals filed
|
|
Superseded by #2173. |
Summary
allow_runtime_fetchandmax_runtime_fetchesfields to the harness schema with validation (negative max rejected, max without allow rejected, backward-compatible defaults)ResolveSkillURLininternal/resolve/for single-URL runtime skill directory resolution — uses forge API (ListDirectoryContents/GetFileContentAtRef) to fetch skill directories,ComputeTreeHashfor integrity verification, andCachePutDir/CacheGetDirfor directory caching, consistent with the directory model from feat(resolve): model skills as directories instead of single files #2139This is PR 1 of 3 for Phase 4 (Runtime Dependency Loading) of ADR-0038. PR 2 adds the in-sandbox
fullsend-fetch-skillscript; PR 3 wires the runner-side socket handler and CLI integration.Changes from rebase on #2139
ResolveSkillURLwas rewritten to use the directory-based skill model introduced in #2139:ComputeTreeHash) instead of file hash (ComputeSHA256)CacheGetDir/CachePutDir) instead of file cache<hash>/tree/) instead of file path (<hash>/content)forge.FakeClientandregisterSkillDirhelpersTest plan
go test ./...— all 29 packages passmake lint— cleanAllowRuntimeFetch/MaxRuntimeFetchesResolveSkillURLtests using forge-based directory model:🤖 Generated with Claude Code