✨ Symlink skills dir for native goose discovery - #136
Conversation
Assisted-By: Claude Code <noreply@anthropic.com> Signed-off-by: Savitha Raghunathan <saveetha13@gmail.com>
Reject repo-controlled .agents symlinks before creating the skills link to prevent writes outside cloneDir. Resolve relative HARNESS_SKILLS_DIR to absolute so the symlink target matches discovery resolution. Assisted-By: Claude Code <noreply@anthropic.com> Signed-off-by: Savitha Raghunathan <saveetha13@gmail.com>
|
Warning Review limit reached
Next review available in: 55 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe migration harness now exposes discovered skills through ChangesSkill discovery and prompt integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant MigrationHarness
participant SkillSource
participant AgentsSkills
participant PromptBuilder
MigrationHarness->>SkillSource: discover skill paths
MigrationHarness->>AgentsSkills: create or update ~/.agents/skills
AgentsSkills-->>MigrationHarness: expose configured skills
MigrationHarness->>PromptBuilder: build prompt without skill content
PromptBuilder-->>MigrationHarness: return prompt with working guidelines
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| logging.Warn("gitignore: %v", err) | ||
| } | ||
|
|
||
| if err := symlinkSkillsDir(cloneDir, skillsDir()); err != nil { |
There was a problem hiding this comment.
what happens with skills that are marked as rules?
There was a problem hiding this comment.
Rules are not in phase1 iirc. I could totally be wrong and if that's the case, harness needs to account for the types either a rule or a skill. @djzager do we support rules for the initial release?
There was a problem hiding this comment.
We could just append the contents of the rules to .goosehints file right?
There was a problem hiding this comment.
we could. .goosehints is goose-specific though and adding opencode support in the harness is in my pipeline, so want to make sure we pick something that works across runtimes. If this is not needed in phase 1, can we use #135 to talk about the approach?
|
I'd point The gitignore write is best-effort: if err := git.EnsureGitignore(cloneDir, []string{
".agents/",
...
}); err != nil {
logging.Warn("gitignore: %v", err)
}and the symlink gets made regardless. Current skills stage specific paths so I don't think it bites today, but the only thing keeping a link to
Tradeoff of the home root is a repo with its own Answering @pranavgaikwad's question above: rules work today, but only by accident. The controller mounts a This PR removes the accident. goose lists name and description in its system instructions and exposes What we could do instead is have the controller mount rule-typed cards at Doesn't need to be this PR, I picked up #135 for it, better place to hash it out than here. |
|
I don't think my @savitharaghunathan on phase 1, I think rules already do something even if they're not a feature yet, a Also the context budget thing I said last comment was wrong, nothing reads |
Assisted-By: Claude Code <noreply@anthropic.com> Signed-off-by: Savitha Raghunathan <saveetha13@gmail.com>
|
@fabianvf |
|
Wrote it up as #138. It lands where this PR already ended up, so nothing here needs to change on my account. The |
ibolton336
left a comment
There was a problem hiding this comment.
Traced the mechanics beyond the diff; they hold together:
- Ordering is right — the link lands after clone, before
goose.StartServe, and only when skills are actually mounted, so no dangling link on skill-less runs. - agent-base pins
HOME=/home/harnessgroup-writable, soos.UserHomeDir()+MkdirAllsurvive OpenShift's random UID. - Skills mount as ImageVolumes (
resolveSkillVolumes→/opt/skills/{name}), so there's no ConfigMap..dataindirection under the link — goose sees real files one symlink hop away. - Harness unit tests pass locally at this head.
One question: has c7ad6e1 had a live run where goose actually lists/loads a skill through the ~/.agents/skills → /opt/skills hop? The unit tests prove the link exists, not that goose traverses it. If the hack/harness-test rig makes that cheap, an assertion there would pin it against future goose version bumps.
|
Tested the symlink in Kind with the full 5-stage workflow. The Fixed by making stage instructions explicit: "Load the 'questionnaire' skill and follow its instructions exactly. Use its templates for the output schema." With that, the agent immediately loaded the skill, read the template and example files, then followed the prescribed phases. The plan stage loaded the skill and all its references. But it wrote PLAN.md at the repo root instead of .konveyor/spec.md and .konveyor/implementation.md — ignoring the skill's explicit output paths even though Phase 4 says "MUST" and "stage is NOT complete until both files are written." Workflow run: savitharaghunathan/coolstore#17 |
Signed-off-by: Savitha Raghunathan <6026527+savitharaghunathan@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@harness/cmd/migration-harness/main_test.go`:
- Line 182: Close the preceding TestShouldRevokeToken function before declaring
TestParseHubTokenID, ensuring its assertions and body are fully terminated so
the two test functions are separate top-level declarations and the package
compiles.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 958c0879-106b-4be3-bd9d-2e97bda2c83f
📒 Files selected for processing (2)
harness/cmd/migration-harness/main.goharness/cmd/migration-harness/main_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- harness/cmd/migration-harness/main.go
Assisted-By: Claude Code <noreply@anthropic.com> Signed-off-by: Savitha Raghunathan <saveetha13@gmail.com>
Define the KONVEYOR_RULES wire format and the ordering constraint it implies, record the konveyor#136 workflow run as evidence for making stage drivers rules, state the cloned repo as untrusted and require the harness to log skill-name collisions, supersede ADR 0001's runtime-discovery claim in the Status line, and drop the stale instruction to ADR 0010 now that konveyor#108 carries it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Define the KONVEYOR_RULES wire format and the ordering constraint it implies, record the konveyor#136 workflow run as evidence for making stage drivers rules, state the cloned repo as untrusted and require the harness to log skill-name collisions, supersede ADR 0001's runtime-discovery claim in the Status line, and drop the stale instruction to ADR 0010 now that konveyor#108 carries it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us>
Closes #135, follow-up to the #70 spike. goose has its own skills implementation and never sees the ones we mount, so the harness concatenating every `SKILL.md` into the prompt is doing work the runtime would do better. This says the harness stops assembling skill content and links `~/.agents/skills` at `/opt/skills` instead, so goose discovers them and `load_skill` resolves supporting files. `skills/javaee-to-quarkus` ships 12 files under `modules/` and `references/` that the agent can't reliably reach today, which is the concrete thing it fixes. The one thing that can't be native is `type: rule`. Nothing in goose forces a skill into context, so rules stay harness-injected. They keep their mount at `/opt/skills` and the controller names them in `KONVEYOR_RULES`, so a rule is both injected and still discoverable for its own `references/`. Unset means inject everything, which is what the harness does today, so an old controller with a new harness doesn't silently drop rules. Verified against goose v1.45.0, the version agent-base pins, and measured in the image: with the link in place `goose skills list` picks up the mounted skill as uid 1001 with the mount read-only. Transcript's in the ADR. Not verified is the `goose serve` path, the probe drives the CLI. The harness half is already implemented in #136. What's left is the rules path, the container-layout globs in `skills/execute`, `skills/verify` and `skills/plan`, and retyping any existing SkillCard written as a constraint, since `type` defaults to `skill`. Numbered 0014 because #108 has 0009-0011 and #106 has 0012-0013 open. Happy to renumber if either lands differently. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added architectural documentation for native skill discovery and progressive skill loading. * Documented how ordinary skills and rule-based skills are handled, including an option to restore legacy behavior. * Added guidance on skill naming, shadowing, validation limitations, discovery mechanics, and rejected alternatives. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…vely - Remove git/commit and KONVEYOR_PARAM_* control from stage skills (ADR 0010) - Name+load the skill in each stage instruction so goose discovers it (konveyor#136) - Fix questionnaire workdir path (/workspace/repo) and plan Inputs typo Signed-off-by: hhpatel14 <hitpatel@redhat.com>
Closes konveyor#135, follow-up to the konveyor#70 spike. goose has its own skills implementation and never sees the ones we mount, so the harness concatenating every `SKILL.md` into the prompt is doing work the runtime would do better. This says the harness stops assembling skill content and links `~/.agents/skills` at `/opt/skills` instead, so goose discovers them and `load_skill` resolves supporting files. `skills/javaee-to-quarkus` ships 12 files under `modules/` and `references/` that the agent can't reliably reach today, which is the concrete thing it fixes. The one thing that can't be native is `type: rule`. Nothing in goose forces a skill into context, so rules stay harness-injected. They keep their mount at `/opt/skills` and the controller names them in `KONVEYOR_RULES`, so a rule is both injected and still discoverable for its own `references/`. Unset means inject everything, which is what the harness does today, so an old controller with a new harness doesn't silently drop rules. Verified against goose v1.45.0, the version agent-base pins, and measured in the image: with the link in place `goose skills list` picks up the mounted skill as uid 1001 with the mount read-only. Transcript's in the ADR. Not verified is the `goose serve` path, the probe drives the CLI. The harness half is already implemented in konveyor#136. What's left is the rules path, the container-layout globs in `skills/execute`, `skills/verify` and `skills/plan`, and retyping any existing SkillCard written as a constraint, since `type` defaults to `skill`. Numbered 0014 because konveyor#108 has 0009-0011 and konveyor#106 has 0012-0013 open. Happy to renumber if either lands differently. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added architectural documentation for native skill discovery and progressive skill loading. * Documented how ordinary skills and rule-based skills are handled, including an option to restore legacy behavior. * Added guidance on skill naming, shadowing, validation limitations, discovery mechanics, and rejected alternatives. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary by CodeRabbit
New Features
/opt/skills, and updates the link when needed.Bug Fixes