[P0] Freeze standard-compatible SKILL.md -> Prolog IR + skill graph contract #173

Open
opened 2026-08-22 02:46:50 +00:00 by lost-rob0t · 2 comments
lost-rob0t commented 2026-08-22 02:46:50 +00:00 (Migrated from github.com)

Parent: #167
Related: #117, #168, #170, #172

Goal

Freeze the canonical SKILL.md package contract for prolog-rlm before implementation.

The runtime must:

  1. load ordinary Agent Skills SKILL.md packages;
  2. accept useful real-world Claude/OpenCode/Agent Zero compatibility variants without making them the canonical format;
  3. optionally read Prolog-owned routing/dependency semantics from the skill itself;
  4. normalize everything into the existing rlm_prompt_compiler skill IR;
  5. derive an internal typed skill graph from that same normalized record;
  6. preserve the existing authority/effect/tool boundaries.

No second prompt compiler, no second skill IR, and no executable Prolog embedded in Markdown/YAML.

RAGE research decision

Read leniently where interoperability requires it; normalize strictly; write the open standard by default.

The canonical emitted form MUST remain valid under the open Agent Skills format. Prolog-specific structure therefore lives under the standard metadata extension point, whose values are strings. Do not require a top-level prolog: YAML object.

Primary references:

Why not a top-level prolog: block?

The open specification defines name, description, optional license, compatibility, metadata, and experimental allowed-tools. metadata is the standard extension point and is specified as string -> string. Strict reference validators may reject unknown top-level fields even though some clients ignore them.

Therefore this issue supersedes the earlier illustrative top-level prolog: example.

Standard compatibility floor

A strict standard skill like this must load:

---
name: review-pr
description: Review a pull request for correctness and regressions. Use when asked to review a PR, diff, or proposed merge.
---

Use the pull-request review workflow.

It must become a valid compiler skill and a valid graph node even with zero Prolog extensions.

Canonical writers/exporters should include at least name + description, obey standard naming/length rules, and use package-relative resource references.

Canonical enriched form

Use the standard metadata map with one namespaced string payload:

---
name: review-pr
description: Review a pull request for correctness and regressions. Use when asked to review a PR, diff, or proposed merge.
metadata:
  prolog-rlm: |-
    {
      "schema": 1,
      "category": "review",
      "aliases": ["pr review", "review pull request"],
      "triggers": [
        {"kind": "phrase", "value": "review pull request", "weight": 80},
        {"kind": "verb", "value": "review", "weight": 50},
        {"kind": "object", "value": "pull_request", "weight": 40}
      ],
      "requires": [
        {"kind": "tool", "name": "git_diff"}
      ],
      "suggests": [],
      "conflicts": [],
      "supersedes": [],
      "requires_capability": null,
      "priority": 200,
      "activation": {"automatic": true}
    }
---

Use the pull-request review workflow.

The prolog-rlm value is JSON text inside a standard string metadata value. JSON is the interchange format only. It MUST be decoded as data through a closed schema, never as a Prolog term and never through read_term/3, call/1, or equivalent executable evaluation.

Why JSON-in-metadata

  • remains inside the standard extension point;
  • string-valued metadata works with strict map[string]string clients;
  • nested routing data remains structured rather than comma-delimited folklore;
  • language-neutral for Claude/OpenCode/Agent Zero/AgentProlog export/import;
  • easy to version with schema;
  • maps safely to closed Prolog terms after validation.

Do not use serialized Prolog terms as the wire representation.

Canonical extension schema v1

Allowed author-supplied keys:

  • schema — required integer for the extension payload; v1 is 1;
  • category — bounded identifier;
  • aliases — bounded list of short strings;
  • triggers — bounded list of closed trigger objects;
  • requires — bounded list of typed unit references;
  • suggests — bounded list of typed unit references;
  • conflicts — bounded list of typed unit references;
  • supersedes — bounded list of typed unit references;
  • requires_capability — null or one closed capability descriptor compatible with the current compiler contract;
  • priority — bounded non-negative routing bias; policy may cap/ignore it by source trust;
  • activation.automatic — boolean; false means automatic Prolog selection is disabled but trusted explicit selection may still activate it.

Trigger objects use a closed vocabulary equivalent to the current compiler:

{"kind":"phrase","value":"review pull request","weight":80}
{"kind":"keyword","value":"github","weight":30}
{"kind":"verb","value":"review","weight":50}
{"kind":"object","value":"pull_request","weight":40}
{"kind":"need","value":"evidence","weight":100}
{"kind":"signal","value":"trusted-runtime-signal","weight":50}

Typed unit references use closed objects, not Prolog syntax:

{"kind":"skill","name":"repository-recon"}
{"kind":"tool","name":"git_diff"}
{"kind":"resource","name":"review_rules"}

Unknown kind values are rejected structurally. No arbitrary functor creation from file text.

Fields that MUST remain host-derived

Do not trust these from SKILL.md as runtime authority/policy:

  • provenance/source trust;
  • package root/location;
  • fingerprint/digest;
  • availability;
  • source precedence / collision winner;
  • execution authority;
  • granted capabilities;
  • effect permissions;
  • handler identity;
  • provider_visible policy;
  • mandatory_context policy.

A skill cannot mark itself trusted, mandatory, executable, or capability-granting.

priority, conflicts, and especially supersedes are routing declarations, not authority. Their effective use may be constrained by host source-precedence/trust policy so a lower-precedence skill cannot suppress a higher-precedence definition merely by declaring an edge.

Standard/vendor field mapping

Open Agent Skills

  • name -> logical skill name / unit:skill(Name) after safe normalization;
  • description -> compiler description/search evidence;
  • Markdown body -> inert skill instruction content;
  • license -> preserved package metadata;
  • compatibility -> preserved compatibility metadata; do not parse free text into capabilities/tools automatically;
  • metadata -> preserve unknown string entries; decode metadata.prolog-rlm only through the versioned closed schema;
  • allowed-tools -> preserve as a declaration/advisory compatibility field only. It never grants Prolog tool capability or bypasses authority/effect policy.

Claude Code compatibility adapter

Recognize common Claude extensions when importing, without requiring them in canonical output:

  • disable-model-invocation: true -> automatic activation disabled;
  • user-invocable -> UI/discovery metadata only, not execution authority;
  • allowed-tools string or list -> normalize as declaration only, never grant authority;
  • model, context, agent, argument-hint, arguments-related fields -> preserve/adapter metadata where useful; do not silently reinterpret them as core Prolog execution semantics.

If both the Prolog extension and a recognized vendor field constrain automatic activation, most restrictive wins.

OpenCode compatibility adapter

Recognize standard metadata and OpenCode-specific activation hints such as metadata.opencode/autoinvoke. false disables automatic activation for the imported skill. Preserve other OpenCode-only presentation fields without making them core semantics.

Agent Zero compatibility

Treat ordinary Agent Zero SKILL.md packages as Agent Skills packages. Do not require Agent Zero-specific plugin/profile state in the portable skill format. Pinned/active-chat behavior remains an Agent Zero harness concern.

Compatibility-mode parsing

Canonical output is strict; import should be pragmatic without becoming unsafe.

Recommended runtime behavior:

  • missing name but safe standard-conforming parent directory exists -> derive the logical name from the directory and emit a diagnostic;
  • invalid/mismatched display name with a safe directory ID -> preserve raw metadata for diagnostics, use deterministic safe identity policy;
  • missing/empty description -> do not invent one. Skill may be retained for trusted explicit activation, but it is not eligible for automatic lexical discovery;
  • technically malformed YAML -> diagnostic + skip unless a narrowly-defined compatibility repair can recover it without ambiguity;
  • unknown standard metadata strings -> preserve/ignore;
  • unknown prolog-rlm keys/kinds -> fail the extension structurally; do not partially execute guessed semantics;
  • path/security failures -> hard reject the package, not warning-only.

This deliberately follows the open client guidance that interoperability problems may warrant warning-level handling for cosmetic spec violations while security and missing-discovery data remain stricter.

Normalization target

After parsing, produce one normalized skill record from which both surfaces derive:

normalized_skill
  identity / logical unit
  description
  activation policy
  category / aliases / triggers
  typed relationships
  capability requirement
  bounded routing priority
  package metadata
  host-derived provenance/fingerprint/root
  body location/body state
  resource index
        |
        +----------------------+
        |                      |
        v                      v
prompt_unit{skill(...)}      skill graph

Do not parse the Markdown body twice and do not maintain a separately-authored graph file.

Internal skill graph

Active node model

Every valid, precedence-resolved loaded skill is a node. Standard-only skills are valid isolated nodes.

Each active node carries at least:

  • logical skill(Name) identity;
  • category;
  • automatic/explicit activation state;
  • host-derived source/provenance;
  • package root/location reference;
  • host-derived fingerprint;
  • declared version string when present, but version is not trusted as identity;
  • availability/eligibility diagnostics.

Shadowed duplicate packages remain diagnostics/lifecycle inputs; the active compiler graph uses the deterministic precedence winner so the existing prompt_catalog keeps one logical skill(Name).

Typed edges

Derive edges only from normalized structured metadata:

requires(A, B)     hard directed dependency
suggests(A, B)     soft directed relationship
conflicts(A, B)    symmetric exclusion semantics
supersedes(A, B)   directed replacement/suppression semantics

Targets may be other skills or other closed compiler units such as tools/resources. A standard-only skill has zero explicit relationship edges.

Do not infer graph edges from natural-language body text. Later AgentProlog/RAGE work may propose candidate edges, but accepted edges must become explicit normalized metadata before they affect runtime behavior.

Graph validation rules

At minimum detect/report:

  • self requires, conflicts, or supersedes;
  • hard requirement cycles among skills;
  • supersession cycles;
  • A requires B while A conflicts B;
  • A requires B while A supersedes B;
  • duplicate edges;
  • missing/unresolved hard skill dependencies;
  • unresolved soft/suppressive targets as diagnostics;
  • lower-precedence suppressive edges that policy refuses to apply.

conflicts is semantically symmetric even if authored once. requires, suggests, and supersedes remain directed.

Graph queries must not read or inject Markdown bodies.

Progressive disclosure

Keep four distinct layers:

  1. discovery metadata — identity, description, activation flags;
  2. host routing/graph metadata — parsed and queryable by Prolog, not automatically provider-visible;
  3. skill body — loaded/injected only after selection;
  4. package resources — indexed safely, contents loaded only on demand.

The open Agent Skills guidance recommends name+description at discovery, full body only after activation, and resources only as needed. prolog-rlm may perform selection host-side rather than exposing the catalog to the model; format compatibility does not require copying another harness's model-driven activation algorithm.

Collision and trust policy

Package discovery and source precedence are host configuration, not file-authored data.

Requirements:

  • deterministic precedence;
  • collision diagnostics;
  • no arbitrary filesystem scan outside configured roots;
  • project/repository skill roots require host trust policy;
  • package-relative paths cannot escape the trusted root;
  • shadowed skills cannot contribute effective suppressive graph edges to the active graph.

Adversarial cases to cover later in implementation/tests

  1. plain strict Agent Skills file with no extension;
  2. enriched standard-valid skill using metadata.prolog-rlm JSON string;
  3. nested YAML object under metadata.prolog-rlm -> rejected as non-portable extension form;
  4. unknown top-level prolog: -> never required; canonical writer does not emit it;
  5. Claude skill missing name but valid directory name;
  6. Claude allowed-tools list despite standard string wording;
  7. OpenCode opencode/autoinvoke=false;
  8. conflicting automatic-activation flags -> restrictive result;
  9. malicious allowed-tools attempting to grant unavailable tools -> no authority change;
  10. malicious provenance/mandatory-context declarations -> ignored/rejected as host-owned;
  11. huge priority/weights/list cardinality -> bounded rejection/cap;
  12. requires cycle;
  13. supersedes cycle;
  14. requires+conflicts contradiction;
  15. lower-precedence skill claims to supersede higher-precedence skill;
  16. duplicate skill names across roots;
  17. path traversal through references/resources;
  18. malformed JSON extension while base skill remains parseable -> explicit extension diagnostic, no guessed partial routing;
  19. unknown schema version -> preserve base skill if safe, ignore/reject unsupported extension semantics explicitly;
  20. standard-only skill -> graph node with zero explicit edges.

Acceptance

  • exact standard-compatible package contract is documented;
  • canonical emitted enriched form uses only standard top-level fields plus string-valued namespaced metadata;
  • ordinary strict Agent Skills files need no Prolog metadata;
  • real-world Claude/OpenCode/Agent Zero variants have documented import policy;
  • versioned metadata.prolog-rlm JSON schema is frozen before loader implementation;
  • exact mapping to the existing prompt_unit{unit:skill(...), ...} IR is documented;
  • host-owned vs skill-authored fields are explicitly separated;
  • allowed-tools never grants Prolog authority;
  • automatic/explicit activation precedence is deterministic;
  • every active loaded skill becomes a graph node;
  • standard-only skills become isolated graph nodes;
  • typed relationship edges derive from the normalized record only;
  • graph contradictions/cycles/unresolved refs have defined diagnostics;
  • graph traversal does not load Markdown bodies;
  • collisions/source precedence are host-controlled and deterministic;
  • progressive disclosure boundaries are explicit;
  • #117 consumes this contract instead of inventing another format.

Non-goals

  • no coding in this RAGE/design slice;
  • no second prompt compiler;
  • no second agent/subagent runtime;
  • no executable Prolog in SKILL.md;
  • no arbitrary call/1 or term evaluation from skill content;
  • no authority/capability/effect grants from skill activation;
  • no model-inferred graph edges affecting runtime without explicit normalized metadata;
  • no lifecycle/evolution policy here (#170/#171);
  • no personal workflow mining here (downstream AgentProlog).

Dependency direction

SKILL.md package
      -> #173 format/normalization/graph contract
      -> #117 loader + deterministic activation
      -> existing rlm_prompt_compiler
      -> #168/#169 evals
      -> #170 lifecycle
      -> #171 evolution
      -> #172 skill-aware delegation

prolog-rlm -> AgentProlog

Implementation should not begin until the format/normalization decisions in this issue are accepted and reconciled with current main.

Parent: #167 Related: #117, #168, #170, #172 ## Goal Freeze the canonical `SKILL.md` package contract for `prolog-rlm` **before implementation**. The runtime must: 1. load ordinary Agent Skills `SKILL.md` packages; 2. accept useful real-world Claude/OpenCode/Agent Zero compatibility variants without making them the canonical format; 3. optionally read Prolog-owned routing/dependency semantics from the skill itself; 4. normalize everything into the existing `rlm_prompt_compiler` skill IR; 5. derive an internal typed skill graph from that same normalized record; 6. preserve the existing authority/effect/tool boundaries. No second prompt compiler, no second skill IR, and no executable Prolog embedded in Markdown/YAML. ## RAGE research decision **Read leniently where interoperability requires it; normalize strictly; write the open standard by default.** The canonical emitted form MUST remain valid under the open Agent Skills format. Prolog-specific structure therefore lives under the standard `metadata` extension point, whose values are strings. Do not require a top-level `prolog:` YAML object. Primary references: - https://agentskills.io/specification - https://agentskills.io/client-implementation/adding-skills-support - https://agentskills.io/skill-creation/best-practices - https://agentskills.io/skill-creation/optimizing-descriptions - https://agentskills.io/skill-creation/evaluating-skills - https://code.claude.com/docs/en/slash-commands - https://opencode.ai/docs/skills - https://www.agent-zero.ai/p/docs/skills/ ### Why not a top-level `prolog:` block? The open specification defines `name`, `description`, optional `license`, `compatibility`, `metadata`, and experimental `allowed-tools`. `metadata` is the standard extension point and is specified as string -> string. Strict reference validators may reject unknown top-level fields even though some clients ignore them. Therefore this issue supersedes the earlier illustrative top-level `prolog:` example. ## Standard compatibility floor A strict standard skill like this must load: ```yaml --- name: review-pr description: Review a pull request for correctness and regressions. Use when asked to review a PR, diff, or proposed merge. --- Use the pull-request review workflow. ``` It must become a valid compiler skill and a valid graph node even with zero Prolog extensions. Canonical writers/exporters should include at least `name` + `description`, obey standard naming/length rules, and use package-relative resource references. ## Canonical enriched form Use the standard `metadata` map with one namespaced string payload: ```yaml --- name: review-pr description: Review a pull request for correctness and regressions. Use when asked to review a PR, diff, or proposed merge. metadata: prolog-rlm: |- { "schema": 1, "category": "review", "aliases": ["pr review", "review pull request"], "triggers": [ {"kind": "phrase", "value": "review pull request", "weight": 80}, {"kind": "verb", "value": "review", "weight": 50}, {"kind": "object", "value": "pull_request", "weight": 40} ], "requires": [ {"kind": "tool", "name": "git_diff"} ], "suggests": [], "conflicts": [], "supersedes": [], "requires_capability": null, "priority": 200, "activation": {"automatic": true} } --- Use the pull-request review workflow. ``` The `prolog-rlm` value is JSON text inside a standard string metadata value. JSON is the interchange format only. It MUST be decoded as data through a closed schema, never as a Prolog term and never through `read_term/3`, `call/1`, or equivalent executable evaluation. ### Why JSON-in-metadata - remains inside the standard extension point; - string-valued metadata works with strict `map[string]string` clients; - nested routing data remains structured rather than comma-delimited folklore; - language-neutral for Claude/OpenCode/Agent Zero/AgentProlog export/import; - easy to version with `schema`; - maps safely to closed Prolog terms after validation. Do not use serialized Prolog terms as the wire representation. ## Canonical extension schema v1 Allowed author-supplied keys: - `schema` — required integer for the extension payload; v1 is `1`; - `category` — bounded identifier; - `aliases` — bounded list of short strings; - `triggers` — bounded list of closed trigger objects; - `requires` — bounded list of typed unit references; - `suggests` — bounded list of typed unit references; - `conflicts` — bounded list of typed unit references; - `supersedes` — bounded list of typed unit references; - `requires_capability` — `null` or one closed capability descriptor compatible with the current compiler contract; - `priority` — bounded non-negative routing bias; policy may cap/ignore it by source trust; - `activation.automatic` — boolean; `false` means automatic Prolog selection is disabled but trusted explicit selection may still activate it. Trigger objects use a closed vocabulary equivalent to the current compiler: ```json {"kind":"phrase","value":"review pull request","weight":80} {"kind":"keyword","value":"github","weight":30} {"kind":"verb","value":"review","weight":50} {"kind":"object","value":"pull_request","weight":40} {"kind":"need","value":"evidence","weight":100} {"kind":"signal","value":"trusted-runtime-signal","weight":50} ``` Typed unit references use closed objects, not Prolog syntax: ```json {"kind":"skill","name":"repository-recon"} {"kind":"tool","name":"git_diff"} {"kind":"resource","name":"review_rules"} ``` Unknown `kind` values are rejected structurally. No arbitrary functor creation from file text. ## Fields that MUST remain host-derived Do **not** trust these from `SKILL.md` as runtime authority/policy: - provenance/source trust; - package root/location; - fingerprint/digest; - availability; - source precedence / collision winner; - execution authority; - granted capabilities; - effect permissions; - handler identity; - `provider_visible` policy; - `mandatory_context` policy. A skill cannot mark itself trusted, mandatory, executable, or capability-granting. `priority`, `conflicts`, and especially `supersedes` are routing declarations, not authority. Their effective use may be constrained by host source-precedence/trust policy so a lower-precedence skill cannot suppress a higher-precedence definition merely by declaring an edge. ## Standard/vendor field mapping ### Open Agent Skills - `name` -> logical skill name / `unit:skill(Name)` after safe normalization; - `description` -> compiler description/search evidence; - Markdown body -> inert skill instruction content; - `license` -> preserved package metadata; - `compatibility` -> preserved compatibility metadata; do not parse free text into capabilities/tools automatically; - `metadata` -> preserve unknown string entries; decode `metadata.prolog-rlm` only through the versioned closed schema; - `allowed-tools` -> preserve as a declaration/advisory compatibility field only. **It never grants Prolog tool capability or bypasses authority/effect policy.** ### Claude Code compatibility adapter Recognize common Claude extensions when importing, without requiring them in canonical output: - `disable-model-invocation: true` -> automatic activation disabled; - `user-invocable` -> UI/discovery metadata only, not execution authority; - `allowed-tools` string or list -> normalize as declaration only, never grant authority; - `model`, `context`, `agent`, `argument-hint`, arguments-related fields -> preserve/adapter metadata where useful; do not silently reinterpret them as core Prolog execution semantics. If both the Prolog extension and a recognized vendor field constrain automatic activation, **most restrictive wins**. ### OpenCode compatibility adapter Recognize standard metadata and OpenCode-specific activation hints such as `metadata.opencode/autoinvoke`. `false` disables automatic activation for the imported skill. Preserve other OpenCode-only presentation fields without making them core semantics. ### Agent Zero compatibility Treat ordinary Agent Zero `SKILL.md` packages as Agent Skills packages. Do not require Agent Zero-specific plugin/profile state in the portable skill format. Pinned/active-chat behavior remains an Agent Zero harness concern. ## Compatibility-mode parsing Canonical output is strict; import should be pragmatic without becoming unsafe. Recommended runtime behavior: - missing `name` but safe standard-conforming parent directory exists -> derive the logical name from the directory and emit a diagnostic; - invalid/mismatched display `name` with a safe directory ID -> preserve raw metadata for diagnostics, use deterministic safe identity policy; - missing/empty `description` -> do not invent one. Skill may be retained for trusted explicit activation, but it is not eligible for automatic lexical discovery; - technically malformed YAML -> diagnostic + skip unless a narrowly-defined compatibility repair can recover it without ambiguity; - unknown standard metadata strings -> preserve/ignore; - unknown `prolog-rlm` keys/kinds -> fail the extension structurally; do not partially execute guessed semantics; - path/security failures -> hard reject the package, not warning-only. This deliberately follows the open client guidance that interoperability problems may warrant warning-level handling for cosmetic spec violations while security and missing-discovery data remain stricter. ## Normalization target After parsing, produce one normalized skill record from which both surfaces derive: ```text normalized_skill identity / logical unit description activation policy category / aliases / triggers typed relationships capability requirement bounded routing priority package metadata host-derived provenance/fingerprint/root body location/body state resource index | +----------------------+ | | v v prompt_unit{skill(...)} skill graph ``` Do not parse the Markdown body twice and do not maintain a separately-authored graph file. ## Internal skill graph ### Active node model Every valid, precedence-resolved loaded skill is a node. Standard-only skills are valid isolated nodes. Each active node carries at least: - logical `skill(Name)` identity; - category; - automatic/explicit activation state; - host-derived source/provenance; - package root/location reference; - host-derived fingerprint; - declared version string when present, but version is not trusted as identity; - availability/eligibility diagnostics. Shadowed duplicate packages remain diagnostics/lifecycle inputs; the active compiler graph uses the deterministic precedence winner so the existing `prompt_catalog` keeps one logical `skill(Name)`. ### Typed edges Derive edges only from normalized structured metadata: ```text requires(A, B) hard directed dependency suggests(A, B) soft directed relationship conflicts(A, B) symmetric exclusion semantics supersedes(A, B) directed replacement/suppression semantics ``` Targets may be other skills or other closed compiler units such as tools/resources. A standard-only skill has zero explicit relationship edges. Do **not** infer graph edges from natural-language body text. Later AgentProlog/RAGE work may propose candidate edges, but accepted edges must become explicit normalized metadata before they affect runtime behavior. ### Graph validation rules At minimum detect/report: - self `requires`, `conflicts`, or `supersedes`; - hard requirement cycles among skills; - supersession cycles; - `A requires B` while `A conflicts B`; - `A requires B` while `A supersedes B`; - duplicate edges; - missing/unresolved hard skill dependencies; - unresolved soft/suppressive targets as diagnostics; - lower-precedence suppressive edges that policy refuses to apply. `conflicts` is semantically symmetric even if authored once. `requires`, `suggests`, and `supersedes` remain directed. Graph queries must not read or inject Markdown bodies. ## Progressive disclosure Keep four distinct layers: 1. **discovery metadata** — identity, description, activation flags; 2. **host routing/graph metadata** — parsed and queryable by Prolog, not automatically provider-visible; 3. **skill body** — loaded/injected only after selection; 4. **package resources** — indexed safely, contents loaded only on demand. The open Agent Skills guidance recommends name+description at discovery, full body only after activation, and resources only as needed. `prolog-rlm` may perform selection host-side rather than exposing the catalog to the model; format compatibility does not require copying another harness's model-driven activation algorithm. ## Collision and trust policy Package discovery and source precedence are host configuration, not file-authored data. Requirements: - deterministic precedence; - collision diagnostics; - no arbitrary filesystem scan outside configured roots; - project/repository skill roots require host trust policy; - package-relative paths cannot escape the trusted root; - shadowed skills cannot contribute effective suppressive graph edges to the active graph. ## Adversarial cases to cover later in implementation/tests 1. plain strict Agent Skills file with no extension; 2. enriched standard-valid skill using `metadata.prolog-rlm` JSON string; 3. nested YAML object under `metadata.prolog-rlm` -> rejected as non-portable extension form; 4. unknown top-level `prolog:` -> never required; canonical writer does not emit it; 5. Claude skill missing `name` but valid directory name; 6. Claude `allowed-tools` list despite standard string wording; 7. OpenCode `opencode/autoinvoke=false`; 8. conflicting automatic-activation flags -> restrictive result; 9. malicious `allowed-tools` attempting to grant unavailable tools -> no authority change; 10. malicious provenance/mandatory-context declarations -> ignored/rejected as host-owned; 11. huge priority/weights/list cardinality -> bounded rejection/cap; 12. `requires` cycle; 13. `supersedes` cycle; 14. requires+conflicts contradiction; 15. lower-precedence skill claims to supersede higher-precedence skill; 16. duplicate skill names across roots; 17. path traversal through references/resources; 18. malformed JSON extension while base skill remains parseable -> explicit extension diagnostic, no guessed partial routing; 19. unknown schema version -> preserve base skill if safe, ignore/reject unsupported extension semantics explicitly; 20. standard-only skill -> graph node with zero explicit edges. ## Acceptance - [ ] exact standard-compatible package contract is documented; - [ ] canonical emitted enriched form uses only standard top-level fields plus string-valued namespaced metadata; - [ ] ordinary strict Agent Skills files need no Prolog metadata; - [ ] real-world Claude/OpenCode/Agent Zero variants have documented import policy; - [ ] versioned `metadata.prolog-rlm` JSON schema is frozen before loader implementation; - [ ] exact mapping to the existing `prompt_unit{unit:skill(...), ...}` IR is documented; - [ ] host-owned vs skill-authored fields are explicitly separated; - [ ] `allowed-tools` never grants Prolog authority; - [ ] automatic/explicit activation precedence is deterministic; - [ ] every active loaded skill becomes a graph node; - [ ] standard-only skills become isolated graph nodes; - [ ] typed relationship edges derive from the normalized record only; - [ ] graph contradictions/cycles/unresolved refs have defined diagnostics; - [ ] graph traversal does not load Markdown bodies; - [ ] collisions/source precedence are host-controlled and deterministic; - [ ] progressive disclosure boundaries are explicit; - [ ] #117 consumes this contract instead of inventing another format. ## Non-goals - no coding in this RAGE/design slice; - no second prompt compiler; - no second agent/subagent runtime; - no executable Prolog in `SKILL.md`; - no arbitrary `call/1` or term evaluation from skill content; - no authority/capability/effect grants from skill activation; - no model-inferred graph edges affecting runtime without explicit normalized metadata; - no lifecycle/evolution policy here (#170/#171); - no personal workflow mining here (downstream AgentProlog). ## Dependency direction ```text SKILL.md package -> #173 format/normalization/graph contract -> #117 loader + deterministic activation -> existing rlm_prompt_compiler -> #168/#169 evals -> #170 lifecycle -> #171 evolution -> #172 skill-aware delegation prolog-rlm -> AgentProlog ``` Implementation should not begin until the format/normalization decisions in this issue are accepted and reconciled with current `main`.
lost-rob0t commented 2026-08-22 02:56:24 +00:00 (Migrated from github.com)

RAGE authoring rule: keep description as the portable primary discovery/routing contract. metadata.prolog-rlm.triggers are optional precision overrides for deterministic evidence the portable description cannot express; they are not a required duplicate trigger language. Standard-only skills should route from name/description through the existing compiler baseline. This keeps exported skills useful in Claude/OpenCode/Agent Zero and lets #168 measure whether custom triggers materially improve precision/recall rather than adding metadata by reflex.

RAGE authoring rule: keep `description` as the portable primary discovery/routing contract. `metadata.prolog-rlm.triggers` are optional precision overrides for deterministic evidence the portable description cannot express; they are not a required duplicate trigger language. Standard-only skills should route from name/description through the existing compiler baseline. This keeps exported skills useful in Claude/OpenCode/Agent Zero and lets #168 measure whether custom triggers materially improve precision/recall rather than adding metadata by reflex.
lost-rob0t commented 2026-08-26 17:12:23 +00:00 (Migrated from github.com)

RAGE reconciliation against canonical main 267697bef10a3fffff7c093e1435ece770e7444b and merged #197:

Executable truth now landed

#197 implemented the standard-compatible confined SKILL.md loader, closed metadata.prolog-rlm normalization, normalized relationship fields (requires, suggests, conflicts, supersedes), one prompt_unit{unit:skill(...)} path into rlm_prompt_compiler, progressive body/resource disclosure, host-owned activation policy, and the default RLM operating skill bundle. The competing skill selector was removed.

Current rlm_skill already stores the typed relationship metadata on the normalized skill record and derives prompt units from that same record. No duplicate parsing/IR is needed.

Remaining #173 gap

Repository search on current main finds no skill_graph implementation or public graph projection. Therefore #173 is not complete and should not be closed merely because #117/#197 landed.

The remaining coherent implementation slice is a read-only typed graph derived only from the normalized skill records:

  • every active catalog skill is a node, including standard-only isolated skills;
  • derive requires, suggests, symmetric conflicts, and directed supersedes edges without reading Markdown bodies/resources;
  • validate self-edges, hard-requirement cycles, supersession cycles, requires+conflicts and requires+supersedes contradictions;
  • unresolved hard skill(...) dependencies fail structurally;
  • unresolved soft/suppressive targets remain explicit diagnostics rather than guessed dependencies;
  • graph metadata remains inert and cannot grant capability, authority, execution, or permanence;
  • graph code consumes skill_catalog_skills/2; it must not become a second selector/compiler.

Adversarial decision

GO to a focused child implementation issue. Do not implement inside #173 itself: this issue explicitly freezes the design and says coding is a non-goal. The child should TDD the public graph projection/validation contract against current normalized records and keep #170/#171 lifecycle/evolution semantics out of scope.

Downstream evidence agrees with ownership: current AgentProlog issues explicitly keep generic skill graph/eval/lifecycle mechanics upstream, while A0 Symbolics remains a thin consumer of the Prolog-RLM compiler/runtime.

RAGE reconciliation against canonical `main` `267697bef10a3fffff7c093e1435ece770e7444b` and merged #197: ## Executable truth now landed #197 implemented the standard-compatible confined `SKILL.md` loader, closed `metadata.prolog-rlm` normalization, normalized relationship fields (`requires`, `suggests`, `conflicts`, `supersedes`), one `prompt_unit{unit:skill(...)}` path into `rlm_prompt_compiler`, progressive body/resource disclosure, host-owned activation policy, and the default RLM operating skill bundle. The competing skill selector was removed. Current `rlm_skill` already stores the typed relationship metadata on the normalized skill record and derives prompt units from that same record. No duplicate parsing/IR is needed. ## Remaining #173 gap Repository search on current `main` finds no `skill_graph` implementation or public graph projection. Therefore #173 is **not complete** and should not be closed merely because #117/#197 landed. The remaining coherent implementation slice is a read-only typed graph derived only from the normalized skill records: - every active catalog skill is a node, including standard-only isolated skills; - derive `requires`, `suggests`, symmetric `conflicts`, and directed `supersedes` edges without reading Markdown bodies/resources; - validate self-edges, hard-requirement cycles, supersession cycles, requires+conflicts and requires+supersedes contradictions; - unresolved hard `skill(...)` dependencies fail structurally; - unresolved soft/suppressive targets remain explicit diagnostics rather than guessed dependencies; - graph metadata remains inert and cannot grant capability, authority, execution, or permanence; - graph code consumes `skill_catalog_skills/2`; it must not become a second selector/compiler. ## Adversarial decision **GO to a focused child implementation issue.** Do not implement inside #173 itself: this issue explicitly freezes the design and says coding is a non-goal. The child should TDD the public graph projection/validation contract against current normalized records and keep #170/#171 lifecycle/evolution semantics out of scope. Downstream evidence agrees with ownership: current AgentProlog issues explicitly keep generic skill graph/eval/lifecycle mechanics upstream, while A0 Symbolics remains a thin consumer of the Prolog-RLM compiler/runtime.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/prolog-rlm#173
No description provided.