diff --git a/README.md b/README.md index ada9a10..f139ebf 100644 --- a/README.md +++ b/README.md @@ -58,16 +58,17 @@ repo-code, PR readiness, artifact, release, and code-comment contracts plus the `contracts-review` action. `skills/ceratops-skill-lifecycle/references/` owns skill-design contracts and skill source-doc tracking. The `skills-contract-review` action refreshes those contracts against registered -best-practice evidence; it does not audit skills or run the repository -validator. The `skills-consistency-review` action audits one skills repository -against the contracts and checks its coupled metadata, action references, -automation consumers, helpers, installer, generated runtime, installed managed -skills, and docs. Each runtime manifest records schema, skill, source identity, -source path, local source-repository root, validation profile, and installer -version. Repository consistency review compares only parsed -`INSTALLER_VERSION` values before installed-skill checks. -The `global-skills-consistency-review` automation discovers required source -repositories and invokes the repo-scoped action once for each repository. +best-practice evidence; it does not audit skills or run the source validator. +The `skills-consistency-review` action audits one direct manifest-backed +installed skill, regardless of its name, against the contracts and checks its +coupled metadata, action references, automation consumers, helpers, installer, +generated runtime, source, and docs. Each runtime manifest records schema, +skill, source identity, source path, local source-repository root, validation +profile, and installer version. Skill consistency review compares only parsed +`INSTALLER_VERSION` values before the selected installed-skill check. +The `global-skills-consistency-review` automation enumerates every direct +manifest-backed skill under `$CODEX_HOME/skills` and invokes the single-skill +action once per skill without repository deduplication. ## Scripts diff --git a/skills/ceratops-skill-lifecycle/SKILL.md b/skills/ceratops-skill-lifecycle/SKILL.md index a382328..63bf6be 100644 --- a/skills/ceratops-skill-lifecycle/SKILL.md +++ b/skills/ceratops-skill-lifecycle/SKILL.md @@ -1,6 +1,6 @@ --- name: ceratops-skill-lifecycle -description: Route Ceratops or compatible skill lifecycle work to action references for create, make-repo-compatible, update, skills-contract-review, skills-consistency-review, fast-change, change-promotion, and ship-to-remote work. Use when Codex should create a skill, make a skills repository Ceratops-compatible, update skill source or shared governance surfaces, refresh Ceratops skill-design contracts, audit one skills repository and its coupled runtime consumers, apply an explicit fast release-branch change, promote committed skill changes into a local release/runtime preview, or ship a staged skills batch through GitHub. +description: Route Ceratops or compatible skill lifecycle work to action references for create, make-repo-compatible, update, skills-contract-review, skills-consistency-review, fast-change, change-promotion, and ship-to-remote work. Use when Codex should create a skill, make a skills repository Ceratops-compatible, update skill source or shared governance surfaces, refresh Ceratops skill-design contracts, audit one manifest-backed installed skill and its coupled source, apply an explicit fast release-branch change, promote committed skill changes into a local release/runtime preview, or ship a staged skills batch through GitHub. --- # Ceratops Skill Lifecycle @@ -22,7 +22,7 @@ local promotion, and remote shipping. - Update an existing skill or shared maintenance surface: `references/update.md` - Refresh Ceratops skill-design contracts from current standards evidence: `references/skills-contract-review.md` -- Audit one skills repository and its coupled runtime consumers: +- Audit one manifest-backed installed skill and its coupled source: `references/skills-consistency-review.md` - Apply an explicit fast release-branch change: `references/fast-change.md` - Promote committed skill changes into a local release branch and runtime @@ -32,7 +32,7 @@ local promotion, and remote shipping. ### Inputs To Capture -- Target skill, repo, branch, release branch, installed runtime expectation, +- Target skill, installed runtime manifest, repo, branch, release branch, action intent, and any explicitly requested staging or shipping step. - Which repo-owned surfaces are in scope: source skill folders, `agents/openai.yaml`, `templates/`, runtime payload declarations, validators, @@ -82,7 +82,8 @@ Infer missing inputs from the current repo state before asking. `$ceratops-governance-lifecycle` action `optimize-skill`. - If the task is Ceratops skill-contract standards upkeep, use `references/skills-contract-review.md`. -- If the task is repository skill consistency and contract compliance, use +- If the task is manifest-backed installed-skill consistency and contract + compliance, use `references/skills-consistency-review.md`. - If the task is a general GitHub repo lifecycle operation, use `$ceratops-gh-repo-lifecycle`. @@ -100,8 +101,9 @@ Infer missing inputs from the current repo state before asking. generation, validator, contract, helper, or doc surface must change. - Use `skills-contract-review` only to refresh the skill-design contracts against current registered best-practice evidence. -- Use `skills-consistency-review` to audit one skills repository against those - contracts and its coupled source, automation, installer, and runtime surfaces. +- Use `skills-consistency-review` to audit one manifest-backed installed skill + against those contracts and its coupled source, automation, installer, and + runtime surfaces. - Use `fast-change` only when the user explicitly asks for a known-safe direct release-branch edit and targeted runtime update. - Use `change-promotion` when committed task-worktree branches are ready to diff --git a/skills/ceratops-skill-lifecycle/references/contracts/skill-deterministic-contract.json b/skills/ceratops-skill-lifecycle/references/contracts/skill-deterministic-contract.json index d562690..eaf3f2e 100644 --- a/skills/ceratops-skill-lifecycle/references/contracts/skill-deterministic-contract.json +++ b/skills/ceratops-skill-lifecycle/references/contracts/skill-deterministic-contract.json @@ -88,7 +88,7 @@ "skill_validation_command": "python skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py --mode skill --skill ", "full_validation_command": "python skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py --mode full", "section_validation_command": "python skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py --mode sections", - "runtime_validation_command": "python skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py --repo-root ", + "runtime_validation_command": "python skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py --repo-root --skill ", "result_contract": "Exit 0 with an ok line when selected deterministic checks pass; nonzero with line-specific errors when they fail." }, "checks": [ @@ -113,7 +113,7 @@ "authoritative installer template INSTALLER_VERSION", "installed runtime manifest installer_version" ], - "pass_condition": "Compatible repositories declare one positive integer INSTALLER_VERSION in scripts/install-skills.py; repository consistency compares only that value, updates missing or lower versions through task worktrees, retains same-version content differences, and runs full validation after synchronization.", + "pass_condition": "Compatible repositories declare one positive integer INSTALLER_VERSION in scripts/install-skills.py; selected-skill consistency compares only that value, updates missing or lower versions through task worktrees, retains same-version content differences, and runs full validation after synchronization.", "source_lines": [ "skills/ceratops-skill-lifecycle/scripts/runtime/synchronize-installers.py:installer_version", "skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py:discover_runtime", @@ -211,7 +211,7 @@ "installed source_repository_root and installer_version", "selected install scope" ], - "pass_condition": "Full installation runs full source-repository validation before building; explicit skill installation validates only selected skills. Runtime manifests record schema, skill, runtime_source_id, source_path, source_repository_root, validation_profile, and installer_version. The builder preflights all selected targets, refuses unmanaged folders, links, invalid ownership, and same-name folders owned by another source; a full install removes only stale folders with the same runtime_source_id, while an explicit targeted install removes none. Runtime validation discovers attributable manifests once and compares complete managed file trees with canonical builder output.", + "pass_condition": "Full installation runs full source-repository validation before building; explicit skill installation validates only selected skills. Runtime manifests record schema, skill, runtime_source_id, source_path, source_repository_root, validation_profile, and installer_version. The builder preflights all selected targets, refuses unmanaged folders, links, invalid ownership, and same-name folders owned by another source; a full install removes only stale folders with the same runtime_source_id, while an explicit targeted install removes none. Runtime validation can select one direct manifest-backed skill and compare only its complete managed file tree with canonical builder output.", "source_lines": [ "skills/ceratops-skill-lifecycle/scripts/runtime/resolve-lifecycle-bundle.py:resolve_bundle", "skills/ceratops-skill-lifecycle/scripts/runtime/install-managed-skills.py:main", @@ -278,7 +278,7 @@ "skill deterministic and nondeterministic contract mappings", "multi-action lifecycle action references and command snippets" ], - "pass_condition": "Full source validation checks rename completeness, current-source skill references, README alignment, and profile-aware source governance; repository runtime checks validate attributable installed ownership and skill identity without one-time stale-term detectors.", + "pass_condition": "Full source validation checks rename completeness, current-source skill references, README alignment, and profile-aware source governance; selected runtime checks validate one direct manifest-backed skill's installed ownership and identity without one-time stale-term detectors.", "source_lines": [ "skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py:check_source_governance_consistency", "skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py:check_skill_contract_remediation_policy", diff --git a/skills/ceratops-skill-lifecycle/references/skills-consistency-review.md b/skills/ceratops-skill-lifecycle/references/skills-consistency-review.md index 8e7f543..e94232a 100644 --- a/skills/ceratops-skill-lifecycle/references/skills-consistency-review.md +++ b/skills/ceratops-skill-lifecycle/references/skills-consistency-review.md @@ -2,9 +2,10 @@ ## Goal -Audit one Ceratops or Ceratops-compatible skills repository as a coupled -source, contract-compliance, metadata, action-reference, automation-consumer, -helper, installer, generated-runtime, and installed-runtime surface. +Audit one direct manifest-backed installed skill, regardless of its name, as a +coupled source, contract-compliance, metadata, action-reference, +automation-consumer, helper, installer, generated-runtime, and +installed-runtime surface. ## Context @@ -12,11 +13,10 @@ helper, installer, generated-runtime, and installed-runtime surface. - (D) Source consistency validator: `python scripts/skills-consistency-source-validator.py --repo-root - --mode full` from the lifecycle bundle. + --mode skill --skill ` from the lifecycle bundle. - (D) Managed runtime validator: `python scripts/runtime/skills-consistency-runtime-validator.py --repo-root - ` from the installed lifecycle bundle when the repository is - expected to be installed. + --skill ` from the installed lifecycle bundle. - (D) Installer synchronization when repair is authorized: `python scripts/runtime/synchronize-installers.py --target-repo-root ` from the installed lifecycle bundle. @@ -35,24 +35,26 @@ helper, installer, generated-runtime, and installed-runtime surface. ### Inputs To Capture -- Target repository root and its `runtime_source_id` and +- Target direct installed skill directory and its `.runtime-manifest.json`; + derive the skill name, source repository root, `runtime_source_id`, and `validation_profile`. - Whether the review is report-only or includes approved source repairs. -- Direct installed runtime root, normally `$CODEX_HOME/skills`, and whether the - repository is expected to be installed there. +- Direct installed runtime root, normally `$CODEX_HOME/skills`. - Existing task worktree for any approved installer or source repair. - Installed automation prompts or repo-owned automation templates that invoke a - skill or action from the target repository. + skill or action from the target skill. Infer missing inputs from the repository and installed manifests before asking. ### Global Automation Caller -- The `global-skills-consistency-review` automation owns required-repository - discovery and invokes this action once per repository. -- The automation may aggregate results and must deduplicate unattributable - malformed-manifest blockers repeated across repository runs, but it must not - replace or narrow this action's repository checks. +- The `global-skills-consistency-review` automation owns direct installed-skill + discovery and invokes this action once per direct skill directory containing + `.runtime-manifest.json`. +- The automation may aggregate results, but it must not deduplicate skills that + share a source repository or make this action perform global discovery. +- Report an unreadable direct runtime manifest as a blocker for that installed + skill without routing it through another skill's review. - Keep standards refresh out of the global consistency run unless it is separately and explicitly requested through `skills-contract-review`. @@ -60,9 +62,12 @@ Infer missing inputs from the repository and installed manifests before asking. ### Boundaries -- Use this action for one source repository and its attributable installed - runtime and automation consumers. Unreadable direct runtime manifests may be - reported as unattributable routing blockers during a global run. +- Use this action for one direct installed skill containing a supported runtime + manifest and its attributable source and automation consumers. Eligibility + depends on the manifest schema and validation profile, never on a Ceratops + name prefix. +- Do not discover or audit sibling installed skills. Global fan-out belongs + only to the automation caller. - Use `skills-contract-review` only when the standards contracts themselves require a best-practice refresh. - Exclude GitHub organization, repository, code, PR, artifact, registry, and @@ -78,47 +83,49 @@ Infer missing inputs from the repository and installed manifests before asking. ### Skill-Specific Rules -- Treat the target repository's `runtime_source_id`, `validation_profile`, - manifest assignments, source skill directories, and installer as its - identity and ownership surface. +- Treat the selected runtime manifest's skill, `runtime_source_id`, + `validation_profile`, source path, source repository root, matching manifest + assignment, and installer as its identity and ownership surface. - Run deterministic validation before AI semantic contract validation. - Run deterministic source checks through - `skills-consistency-source-validator.py` and installed-runtime checks through - `skills-consistency-runtime-validator.py`. + `skills-consistency-source-validator.py --mode skill --skill ` + and installed-runtime checks through + `skills-consistency-runtime-validator.py --skill `. - Validate every applicable non-deterministic contract check through evidence-backed AI validation. -- Let the runtime validator discover attributable manifests before validating - their identities, installer versions, and complete managed file trees. +- Let the runtime validator read the selected direct manifest before validating + its identity, installer version, and complete managed file tree. - Compare installers only by parsed integer `INSTALLER_VERSION`; retain same- or higher-version differences and synchronize missing or lower versions only through an approved task worktree. -- Inventory only direct installed-skill directories containing +- Accept only a direct installed-skill directory containing `.runtime-manifest.json`; do not descend into `.system`, plugin caches, - bundled providers, or unmanaged folders. + bundled providers, unmanaged folders, or sibling skills. - Deep-read only coupled surfaces needed to evaluate a contract check, identity collision, unresolved resource, stale reference, trigger conflict, helper contract, or source/runtime mismatch. - Record each non-deterministic check as `pass`, `fail`, `approved_drift`, - `blocked`, or `not_applicable` for every validated source skill. + `blocked`, or `not_applicable` for the selected source skill. ## Workflow -### 1. Inventory the repository surface +### 1. Resolve the selected skill surface -- Read the section manifest and enumerate every source skill, action reference, - metadata file, runtime payload declaration, relevant helper and caller, - installer, validator, and public document. +- Read the selected direct runtime manifest and resolve its source repository, + source skill, section-manifest assignment, action references, metadata, + runtime payloads, relevant helpers and callers, installer, validator, and + public documentation. - Find repo-owned automation templates and installed automation prompts that - explicitly invoke the repository's skills or actions. -- Build an identity map from source skill names through metadata, action lists, - docs, runtime payloads, installed manifests, and automation consumers. + explicitly invoke the selected skill or its actions. +- Build an identity map for the selected skill through metadata, action lists, + docs, runtime payloads, its installed manifest, and automation consumers. ### 2. Run deterministic contract checks -- Resolve the validator from the target source checkout when present, - otherwise from the installed lifecycle bundle. -- Run `--mode full --repo-root ` so common and profile-specific - source checks execute together. +- Resolve the validator from the target source checkout when present, otherwise + from the installed lifecycle bundle. +- Run `--mode skill --skill --repo-root ` so common and + profile-specific source checks execute only for the selected skill. - Map every validator finding to its deterministic contract check ID and owning source repair. Do not treat a passing validator as evidence for any non-deterministic check. @@ -127,23 +134,21 @@ Infer missing inputs from the repository and installed manifests before asking. ### 3. Validate installer and runtime coherence -- When the repository is expected to be installed, run the managed runtime - validator once; otherwise classify installed-runtime validation as not - applicable. -- Reject malformed attributable manifests; compare manifest schema, skill, +- Run the managed runtime validator once with `--skill `. +- Reject a malformed selected manifest; compare manifest schema, skill, `runtime_source_id`, `source_path`, `source_repository_root`, `validation_profile`, and `installer_version` with source ownership. -- Detect duplicate identities or source paths, unresolved source or local - resources, missing or stale installed skills, stale shared-section output, - frontmatter drift, source/runtime ownership conflicts, and stale cross-skill - references. +- Detect unresolved source or local resources, a missing or stale installed + skill, stale shared-section output, frontmatter drift, source/runtime + ownership conflicts, and stale cross-skill references attributable to the + selected skill. - When an installer is missing or lower-version and repair is approved, run the synchronization helper in the task worktree and require successful full target-repository validation before continuing. ### 4. Validate non-deterministic contract compliance -- Validate every source skill against every applicable check in +- Validate the selected source skill against every applicable check in `skill-nondeterministic-contract.json`. - Check semantic agreement across trigger descriptions, metadata prompts, parent skill routing, action references, inputs, boundaries, workflow, @@ -170,19 +175,19 @@ Infer missing inputs from the repository and installed manifests before asking. after an approved repair. - Revalidate only affected non-deterministic checks and coupled semantic surfaces. -- Account for every deterministic and non-deterministic contract check and - every repository skill before completion. +- Account for every deterministic and non-deterministic contract check for the + selected skill before completion. ## Done When ### Completion Gate -- Every source skill is inventoried and evaluated against every applicable - deterministic and non-deterministic contract check. -- Full source validation passes or every finding has an owning file and smallest - credible repair. -- Runtime discovery precedes validation internally, and every attributable - installed manifest and managed file is checked or its blocker is named. +- The selected source skill is inventoried and evaluated against every + applicable deterministic and non-deterministic contract check. +- Targeted source validation passes or every finding has an owning file and + smallest credible repair. +- The selected runtime manifest is read before validation, and every managed + file for that installed skill is checked or its blocker is named. - Skill text, action routing, metadata, automation consumers, helpers, installers, runtime payloads, installed runtime, docs, and validator claims agree or every mismatch is classified. @@ -192,7 +197,7 @@ Infer missing inputs from the repository and installed manifests before asking. Report only: -- target repository, profile, source-skill count, and installed managed count +- target skill, installed path, source repository, profile, and managed count - deterministic contract and validation outcome - non-deterministic contract results by failed, blocked, approved-drift, or not-applicable check; omit passing detail diff --git a/skills/ceratops-skill-lifecycle/references/skills-contract-review.md b/skills/ceratops-skill-lifecycle/references/skills-contract-review.md index 21358e8..3f580fc 100644 --- a/skills/ceratops-skill-lifecycle/references/skills-contract-review.md +++ b/skills/ceratops-skill-lifecycle/references/skills-contract-review.md @@ -33,9 +33,10 @@ Infer missing inputs from the contract files before asking. - Use this action only to maintain the skill source-doc registry and the two skill-design contracts. - Do not audit whether any source or installed skill satisfies the contracts; - use `skills-consistency-review` for repository compliance. -- Do not run `skills-consistency-source-validator.py`; repository validation - belongs to `skills-consistency-review`. + use `skills-consistency-review` for manifest-backed installed-skill + compliance. +- Do not run `skills-consistency-source-validator.py`; targeted skill + validation belongs to `skills-consistency-review`. - Do not inspect unrelated metadata, shared sections, runtime payloads, automation prompts, helpers, installers, or installed runtime copies. diff --git a/skills/ceratops-skill-lifecycle/references/update.md b/skills/ceratops-skill-lifecycle/references/update.md index e362a2f..ad36376 100644 --- a/skills/ceratops-skill-lifecycle/references/update.md +++ b/skills/ceratops-skill-lifecycle/references/update.md @@ -41,8 +41,9 @@ Infer missing inputs from current repo state before asking. `create`. - If the task is Ceratops skill-contract standards upkeep, return to the parent skill and select `skills-contract-review`. -- If the task is repository skill consistency or contract compliance, return - to the parent skill and select `skills-consistency-review`. +- If the task is manifest-backed installed-skill consistency or contract + compliance, return to the parent skill and select + `skills-consistency-review`. - If the task only promotes already-prepared committed changes, select `change-promotion`. diff --git a/skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py b/skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py index 65c19aa..98a490c 100644 --- a/skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py +++ b/skills/ceratops-skill-lifecycle/scripts/runtime/skills-consistency-runtime-validator.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 -"""Validate managed runtime skills for one source repository. +"""Validate managed runtime skills for one source repository or selected skill. Discovery never descends into plugin caches or unmanaged skill folders. Repository identity filters well-formed manifests while malformed direct manifests remain visible because their owner cannot be trusted. Validation then -compares each installed managed tree with the canonical builder output. +compares each selected managed tree with the canonical builder output. """ from __future__ import annotations @@ -76,11 +76,17 @@ def read_manifest(skill_dir: pathlib.Path) -> tuple[Mapping[str, object] | None, return (value, None) if isinstance(value, Mapping) else (None, "manifest must be a JSON object") -def managed_directories(runtime_root: pathlib.Path) -> list[pathlib.Path]: - """Return only direct runtime folders containing the managed manifest.""" +def managed_directories( + runtime_root: pathlib.Path, + selected_skill: str | None = None, +) -> list[pathlib.Path]: + """Return selected direct runtime folders containing the managed manifest.""" if not runtime_root.is_dir(): return [] + if selected_skill is not None: + selected = runtime_root / selected_skill + return [selected] if selected.is_dir() and (selected / MANIFEST_NAME).is_file() else [] return sorted( path for path in runtime_root.iterdir() if path.is_dir() and (path / MANIFEST_NAME).is_file() ) @@ -121,13 +127,26 @@ def source_context( def discover_runtime( repo_root: pathlib.Path, runtime_root: pathlib.Path, + selected_skill: str | None = None, ) -> tuple[list[dict[str, object]], list[str], Mapping[str, object] | None, str | None, set[str]]: - """Discover repository-owned manifests and validate their identity fields.""" + """Discover selected repository-owned manifests and validate identity fields.""" errors: list[str] = [] records: list[dict[str, object]] = [] source_manifest, source_id, source_profile, skill_names, source_errors = source_context(repo_root) errors.extend(source_errors) + if selected_skill is not None: + if pathlib.PurePath(selected_skill).name != selected_skill: + errors.append("selected skill must be one direct runtime directory name") + skill_names = set() + elif selected_skill not in skill_names: + errors.append(f"{selected_skill}: source repository has no matching skill") + skill_names = set() + else: + skill_names = {selected_skill} + selected_manifest = runtime_root / selected_skill / MANIFEST_NAME + if not selected_manifest.is_file(): + errors.append(f"{selected_skill}: direct runtime manifest is missing") authoritative_version = installer_version(TEMPLATE) if authoritative_version is None: errors.append("authoritative installer version is missing or invalid") @@ -136,7 +155,7 @@ def discover_runtime( if source_version is None or source_version < authoritative_version: errors.append("source repository installer is missing or outdated") - for skill_dir in managed_directories(runtime_root): + for skill_dir in managed_directories(runtime_root, selected_skill): manifest, error = read_manifest(skill_dir) if manifest is None: errors.append(f"{skill_dir.name}: unreadable runtime manifest: {error}") @@ -293,15 +312,22 @@ def validate_runtime( def main() -> int: - """Discover and validate one repository's installed managed runtime.""" + """Discover and validate one repository or selected installed skill.""" - parser = argparse.ArgumentParser(description="Validate managed runtime skills for one source repository.") + parser = argparse.ArgumentParser( + description="Validate managed runtime skills for one source repository or selected skill." + ) parser.add_argument("--repo-root", required=True, type=pathlib.Path) parser.add_argument("--runtime-root", type=pathlib.Path) + parser.add_argument("--skill", help="Validate only this direct manifest-backed runtime skill.") args = parser.parse_args() repo_root = args.repo_root.resolve() runtime_root = (args.runtime_root or default_runtime_root()).resolve() - records, errors, source_manifest, source_id, skill_names = discover_runtime(repo_root, runtime_root) + records, errors, source_manifest, source_id, skill_names = discover_runtime( + repo_root, + runtime_root, + args.skill, + ) if not errors and source_manifest is not None: errors.extend( validate_runtime( diff --git a/skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py b/skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py index 00d750c..f931dc5 100644 --- a/skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py +++ b/skills/ceratops-skill-lifecycle/scripts/skills-consistency-source-validator.py @@ -757,7 +757,11 @@ def check_validation_command_surface() -> list[str]: for field in ("source_repository_root", "installer_version"): if field not in builder_text or field not in runtime_validator_text: errors.append(f"runtime building and validation must both own manifest field {field}") - if "compare_managed_tree" not in runtime_validator_text or '"--mode"' in runtime_validator_text: + if ( + "compare_managed_tree" not in runtime_validator_text + or '"--skill"' not in runtime_validator_text + or '"--mode"' in runtime_validator_text + ): errors.append("runtime validator must compare managed trees through one command") if RUNTIME_MANIFEST_SCHEMA not in bundle_resolver_text or "installed_bundle_supported" not in bundle_resolver_text: errors.append("lifecycle bundle resolver must enforce installed runtime capability before checkout fallback") diff --git a/tests/test_skill_runtime_multi_repo.py b/tests/test_skill_runtime_multi_repo.py index 65474ab..b1e4bd1 100644 --- a/tests/test_skill_runtime_multi_repo.py +++ b/tests/test_skill_runtime_multi_repo.py @@ -549,3 +549,38 @@ def test_repository_review_uses_only_attributable_direct_manifest_folders(tmp_pa assert stale.returncode == 1 assert "managed file content differs: SKILL.md" in stale.stderr + + +def test_selected_skill_review_does_not_audit_sibling_skills(tmp_path: pathlib.Path) -> None: + repo = tmp_path / "compatible" + install_root = tmp_path / "installed" + create_compatible_repo(repo, "example/compatible", ["alpha-tool", "beta-tool"]) + assert run_builder(repo, install_root, "--remove-stale").returncode == 0 + (install_root / "beta-tool" / "SKILL.md").write_text( + "stale\n", + encoding="utf-8", + newline="\n", + ) + + selected = subprocess.run( + [ + sys.executable, + str(RUNTIME_VALIDATOR), + "--repo-root", + str(repo), + "--runtime-root", + str(install_root), + "--skill", + "alpha-tool", + ], + capture_output=True, + text=True, + check=False, + ) + + assert selected.returncode == 0, selected.stderr + assert json.loads(selected.stdout) == { + "managed": 1, + "runtime_source_id": "example/compatible", + "status": "valid", + }