Skip to content

feat(knowledge): allow nested subdirectories in pack file paths#60

Merged
ysyneu merged 1 commit into
mainfrom
feat/knowledge-pack-subdirs
Jun 9, 2026
Merged

feat(knowledge): allow nested subdirectories in pack file paths#60
ysyneu merged 1 commit into
mainfrom
feat/knowledge-pack-subdirs

Conversation

@ysyneu

@ysyneu ysyneu commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Why

Companion to fc-safari #142 (knowledge-pack subdirectory support). Safari now accepts nested rel_paths, but the runner's path layer assumed a flat single leaf and rejected anything deeper. Without this change a nested knowledge file syncs up to the cloud but fails to stage back onto the workspace on the next session — StageKnowledgeFiles and ReconcileKnowledgeManifest both gate on validateKnowledgeRelPath.

Change

  • validateKnowledgeRelPath — accept knowledge/<scope>/<leaf…> with len(parts) >= 3, validating every leaf segment (no empty / . / .. / dotfile) so a nested path still cannot escape the scope directory when joined onto the workspace root.
  • walkKnowledgeTree — rewrite with filepath.WalkDir so reconcile discovers (and can prune) nested files instead of ignoring subdirectories.

StageKnowledgeFiles already MkdirAlls parent dirs, so nested files land correctly once validation passes.

Verification

  • go build ./... clean; go test ./environment/... green; gofmt clean.
  • New tests: TestStageKnowledgeFiles_NestedSubdir, TestReconcileKnowledgeManifest_Nested (nested kept + pruned-as-orphan); extended TestValidateKnowledgeRelPath and TestStageKnowledgeFiles_RejectedPaths (traversal / nested-dotfile / empty-segment still rejected).
  • Adversarial path-traversal audit (30k-case brute-force + hand-tracing): validation runs on the raw split string before filepath.Join, so a .. prefix is caught and never reaches the write sink. No escape found.

Rollout

main is the runner's sole release trunk. After merge this needs a v* tag release + fleet rollout (BYOC self-update / sandbox image rebuild + advertised version bump) for the subdirectory round-trip to work end-to-end against deployed runners.

🤖 Generated with Claude Code

Safari now lets knowledge-pack files live in subdirectories
(knowledge/<scope>/<sub>/<file>). The runner's path layer assumed a flat
single leaf and rejected anything deeper, so a nested file would sync up
to the cloud but fail to stage back onto the workspace on the next
session (StageKnowledgeFiles / ReconcileKnowledgeManifest both gate on
validateKnowledgeRelPath).

- validateKnowledgeRelPath: accept knowledge/<scope>/<leaf...> with
  len>=3, validating every leaf segment (no empty/`.`/`..`/dotfile) so a
  nested path still can't escape the scope dir when joined onto the root.
- walkKnowledgeTree: rewrite with filepath.WalkDir so reconcile discovers
  (and can prune) nested files instead of ignoring subdirectories.

StageKnowledgeFiles already MkdirAll's parent dirs, so nested files land
correctly once validation passes.
@ysyneu ysyneu merged commit 25f833b into main Jun 9, 2026
10 checks passed
@ysyneu ysyneu deleted the feat/knowledge-pack-subdirs branch June 9, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant