Ship staged skill release - #163
Conversation
# Conflicts: # README.md # skills/ceratops-repo-lifecycle/scripts/ship-repository.py
…ase-local-merge # Conflicts: # AGENTS.history.json # AGENTS.md # CHANGELOG.md # CONTRIBUTING.md # README.md # skills/ceratops-repo-lifecycle/references/skill-sections-template.json # skills/ceratops-skill-lifecycle/references/make-repo-compatible.md # skills/ceratops-skill-lifecycle/references/update.md # skills/ceratops-skill-lifecycle/scripts/runtime/resolve-lifecycle-bundle.py # skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py # skills/ceratops-skill-lifecycle/scripts/templates/skill-sections-template.json # skills/skill-sections.json # templates/skill-sections-template.json # tests/test_skill_runtime_multi_repo.py
…e-local-merge # Conflicts: # AGENTS.history.json # skills/ceratops-repo-lifecycle/scripts/ship-repository.py # skills/ceratops-skill-lifecycle/SKILL.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2bbba03a55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if source.is_dir(): | ||
| shutil.copytree(source, destination, ignore=shutil.ignore_patterns(*IGNORED_NAMES), dirs_exist_ok=True) |
There was a problem hiding this comment.
Reject links nested inside runtime payload directories
When a declared payload is a directory containing a symlink or reparse point, only the directory itself is checked before copytree recursively follows the nested link. A compatible repository can therefore copy files from outside its checkout—such as credentials or other private data—into an installed skill. Traverse and reject unsafe descendants before copying, as the managed runtime builder already does.
Useful? React with 👍 / 👎.
| for skill in skills: | ||
| replace_skill(staging, destination, source_id, skill) |
There was a problem hiding this comment.
Validate every destination before replacing any skill
When multiple skills are selected and a later destination is foreign-owned or has malformed ownership metadata, earlier destinations have already been deleted and replaced before the later check raises. The installer consequently exits nonzero while leaving a partially upgraded, mixed-version runtime. Preflight ownership for the entire selected set before this loop, or make the replacements rollback-safe.
Useful? React with 👍 / 👎.
| USER_HOME_RE = re.compile( | ||
| r"(?:[A-Z]:[\\/]+Users[\\/]+[^\\/\s\"']+|" | ||
| r"[\\/]+(?:Users|home)[\\/]+[^\\/\s\"']+)", | ||
| re.IGNORECASE, |
There was a problem hiding this comment.
Redact the actual home directory on root-style Unix accounts
When --include-run is used under an account whose home is not /home/<name>—notably /root in containers—the sanitizer does not match the user's home path, so semantic summaries expose the full local absolute path. The added closure-mode test already fails in such an environment because /root/private/tool.py remains visible; derive and redact Path.home() (and the configured profile root) rather than recognizing only /home and /Users layouts.
Useful? React with 👍 / 👎.
Staged skill lifecycle release branch.