Skip to content

Add Manifest-Driven Verbatim Tree Propagation #797

Description

@ptr727

Summary

Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

Root Cause

GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

Architecture

Keep these responsibilities separate:

  • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
  • scripts/skills_install.py installs hub skills for local agents on a host.
  • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
  • spec/audit.py measures downstream fidelity against promoted hub main.
  • Standup and resync decide when the carry tool applies changes.

The data flow is:

.agents/skills/
|
+-- build_dist.py --> .github/skills/
| |
| +-- carry tool --> downstream .github/skills/
|
+-- skills_install.py --> host-global agent installations

Manifest Model

Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

{
"source": ".github/skills",
"target": ".github/skills",
"fidelity": "verbatim-tree",
"appliesTo": "*",
"include": ["**/*"],
"prune": true
}

The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

verbatim-tree means:

  • Every included source file exists at the corresponding target path.
  • File bytes match after only the normalization explicitly allowed by the fidelity model.
  • No undeclared file or directory exists under a prune: true target.
  • A source addition becomes required downstream.
  • A retired source path is removed downstream.
  • The target root exists even when the resolved source inventory is empty.

Reject overlapping declarations whose ownership or prune boundaries conflict.

Carry Tool Interface

Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

check must report:

  • The hub commit used as canonical input.
  • The resolved repository name, types, and applicable declarations.
  • Missing target files and directories.
  • Modified target files.
  • Extra paths inside pruned targets.
  • Source and target digests for each declared tree.
  • An unreadable or unsafe state as undecided or failed, never clean.

apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

Write Safety

Before applying changes, the tool must:

  1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
  2. Resolve the named repository through registry/repos.json.
  3. Confirm the target origin matches the registry entry.
  4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
  5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
  6. Refuse unrelated target changes instead of overwriting or bundling them.
  7. Resolve every source and target beneath its declared root before writing.
  8. Reject symlinks in either tree rather than following them.
  9. Restrict deletion to extra paths under an applicable prune: true target.
  10. Preserve unrelated files outside declared target roots.

Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

Skills as the First Consumer

Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

Before fleet rollout, verify that every skill is safe when discovered downstream:

  • Hub-context-only skills clearly prevent activation from the wrong context.
  • Skills do not assume .agents/skills/ exists downstream.
  • Sibling skill routing uses skill names or distribution-relative language.
  • Bundled references and scripts travel with their parent skill.
  • References to repository rules resolve through carried repository documents.
  • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

Standup, Resync, and Audit Integration

  • Standup applies required tree declarations when establishing a repository baseline.
  • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
  • Audit classifies an absent tree as missing baseline and a stale tree as drift.
  • Audit compares downstream ground-truth branches against fetched hub main.
  • Retired tree content is removed only through the declaration's explicit prune authority.
  • The registry and applicability model decide which repositories receive each tree.

Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

CI and Freshness

Separate integrity from fleet freshness.

A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

Use one or more of these mechanisms for freshness:

  • A scheduled or manually dispatched conformance check against current hub main.
  • Fleet audit from ProjectTemplate.
  • Propagation pull requests opened when promoted carried content changes.

If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

Required Tests

Test the carry engine against temporary hub and downstream trees. Cover at least:

  • A clean verbatim tree.
  • A missing target root.
  • A missing file.
  • A modified same-size file.
  • An extra file and extra directory under a pruned target.
  • A source addition.
  • A retired source path.
  • An empty source inventory whose target root must exist.
  • A source or target symlink.
  • A target outside the repository root.
  • An overlapping or conflicting declaration.
  • An inapplicable declaration selected by repository type.
  • A mismatched target origin or registry identity.
  • A dirty target carrying unrelated changes.
  • A failed source read that must not appear clean.
  • Idempotent apply followed by a clean check.
  • Preservation of unrelated paths outside the declared target.

Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

Acceptance Criteria

  • .agents/skills/ remains the only hand-authored skill source.
  • ProjectTemplate generates the complete .github/skills/ distribution.
  • A generic manifest declaration owns the downstream .github/skills/ tree.
  • The carry tool provides deterministic check and apply modes.
  • Standup and resync use the carry tool rather than manual copying.
  • Audit detects absent, stale, modified, and extra downstream skill content.
  • Retiring a canonical skill removes it through explicit prune semantics.
  • Downstream repositories contain every skill path their Copilot bootstrap names.
  • Host-global skill installation continues unchanged.
  • Required CI checks prove integrity without depending on moving hub main.
  • A scheduled, audit, or propagation path reports fleet freshness.
  • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

Relationship to #793 and PR #799

#793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentsAgents instructionsskillsAgent skill

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
      Skip to content

      Add Manifest-Driven Verbatim Tree Propagation #797

      Description

      @ptr727

      Summary

      Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

      The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

      Root Cause

      GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

      ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

      The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

      Architecture

      Keep these responsibilities separate:

      • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
      • scripts/skills_install.py installs hub skills for local agents on a host.
      • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
      • spec/audit.py measures downstream fidelity against promoted hub main.
      • Standup and resync decide when the carry tool applies changes.

      The data flow is:

      .agents/skills/
      |
      +-- build_dist.py --> .github/skills/
      | |
      | +-- carry tool --> downstream .github/skills/
      |
      +-- skills_install.py --> host-global agent installations
      

      Manifest Model

      Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

      {
      "source": ".github/skills",
      "target": ".github/skills",
      "fidelity": "verbatim-tree",
      "appliesTo": "*",
      "include": ["**/*"],
      "prune": true
      }

      The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

      verbatim-tree means:

      • Every included source file exists at the corresponding target path.
      • File bytes match after only the normalization explicitly allowed by the fidelity model.
      • No undeclared file or directory exists under a prune: true target.
      • A source addition becomes required downstream.
      • A retired source path is removed downstream.
      • The target root exists even when the resolved source inventory is empty.

      Reject overlapping declarations whose ownership or prune boundaries conflict.

      Carry Tool Interface

      Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

      python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
      python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

      check must report:

      • The hub commit used as canonical input.
      • The resolved repository name, types, and applicable declarations.
      • Missing target files and directories.
      • Modified target files.
      • Extra paths inside pruned targets.
      • Source and target digests for each declared tree.
      • An unreadable or unsafe state as undecided or failed, never clean.

      apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

      Write Safety

      Before applying changes, the tool must:

      1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
      2. Resolve the named repository through registry/repos.json.
      3. Confirm the target origin matches the registry entry.
      4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
      5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
      6. Refuse unrelated target changes instead of overwriting or bundling them.
      7. Resolve every source and target beneath its declared root before writing.
      8. Reject symlinks in either tree rather than following them.
      9. Restrict deletion to extra paths under an applicable prune: true target.
      10. Preserve unrelated files outside declared target roots.

      Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

      Skills as the First Consumer

      Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

      Before fleet rollout, verify that every skill is safe when discovered downstream:

      • Hub-context-only skills clearly prevent activation from the wrong context.
      • Skills do not assume .agents/skills/ exists downstream.
      • Sibling skill routing uses skill names or distribution-relative language.
      • Bundled references and scripts travel with their parent skill.
      • References to repository rules resolve through carried repository documents.
      • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

      The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

      Standup, Resync, and Audit Integration

      • Standup applies required tree declarations when establishing a repository baseline.
      • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
      • Audit classifies an absent tree as missing baseline and a stale tree as drift.
      • Audit compares downstream ground-truth branches against fetched hub main.
      • Retired tree content is removed only through the declaration's explicit prune authority.
      • The registry and applicability model decide which repositories receive each tree.

      Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

      CI and Freshness

      Separate integrity from fleet freshness.

      A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

      Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

      Use one or more of these mechanisms for freshness:

      • A scheduled or manually dispatched conformance check against current hub main.
      • Fleet audit from ProjectTemplate.
      • Propagation pull requests opened when promoted carried content changes.

      If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

      Required Tests

      Test the carry engine against temporary hub and downstream trees. Cover at least:

      • A clean verbatim tree.
      • A missing target root.
      • A missing file.
      • A modified same-size file.
      • An extra file and extra directory under a pruned target.
      • A source addition.
      • A retired source path.
      • An empty source inventory whose target root must exist.
      • A source or target symlink.
      • A target outside the repository root.
      • An overlapping or conflicting declaration.
      • An inapplicable declaration selected by repository type.
      • A mismatched target origin or registry identity.
      • A dirty target carrying unrelated changes.
      • A failed source read that must not appear clean.
      • Idempotent apply followed by a clean check.
      • Preservation of unrelated paths outside the declared target.

      Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

      Acceptance Criteria

      • .agents/skills/ remains the only hand-authored skill source.
      • ProjectTemplate generates the complete .github/skills/ distribution.
      • A generic manifest declaration owns the downstream .github/skills/ tree.
      • The carry tool provides deterministic check and apply modes.
      • Standup and resync use the carry tool rather than manual copying.
      • Audit detects absent, stale, modified, and extra downstream skill content.
      • Retiring a canonical skill removes it through explicit prune semantics.
      • Downstream repositories contain every skill path their Copilot bootstrap names.
      • Host-global skill installation continues unchanged.
      • Required CI checks prove integrity without depending on moving hub main.
      • A scheduled, audit, or propagation path reports fleet freshness.
      • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

      Relationship to #793 and PR #799

      #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

      This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        agentsAgents instructionsskillsAgent skill

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
          Skip to content

          Add Manifest-Driven Verbatim Tree Propagation #797

          Description

          @ptr727

          Summary

          Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

          The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

          Root Cause

          GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

          ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

          The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

          Architecture

          Keep these responsibilities separate:

          • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
          • scripts/skills_install.py installs hub skills for local agents on a host.
          • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
          • spec/audit.py measures downstream fidelity against promoted hub main.
          • Standup and resync decide when the carry tool applies changes.

          The data flow is:

          .agents/skills/
          |
          +-- build_dist.py --> .github/skills/
          | |
          | +-- carry tool --> downstream .github/skills/
          |
          +-- skills_install.py --> host-global agent installations
          

          Manifest Model

          Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

          {
          "source": ".github/skills",
          "target": ".github/skills",
          "fidelity": "verbatim-tree",
          "appliesTo": "*",
          "include": ["**/*"],
          "prune": true
          }

          The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

          verbatim-tree means:

          • Every included source file exists at the corresponding target path.
          • File bytes match after only the normalization explicitly allowed by the fidelity model.
          • No undeclared file or directory exists under a prune: true target.
          • A source addition becomes required downstream.
          • A retired source path is removed downstream.
          • The target root exists even when the resolved source inventory is empty.

          Reject overlapping declarations whose ownership or prune boundaries conflict.

          Carry Tool Interface

          Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

          python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
          python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

          check must report:

          • The hub commit used as canonical input.
          • The resolved repository name, types, and applicable declarations.
          • Missing target files and directories.
          • Modified target files.
          • Extra paths inside pruned targets.
          • Source and target digests for each declared tree.
          • An unreadable or unsafe state as undecided or failed, never clean.

          apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

          Write Safety

          Before applying changes, the tool must:

          1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
          2. Resolve the named repository through registry/repos.json.
          3. Confirm the target origin matches the registry entry.
          4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
          5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
          6. Refuse unrelated target changes instead of overwriting or bundling them.
          7. Resolve every source and target beneath its declared root before writing.
          8. Reject symlinks in either tree rather than following them.
          9. Restrict deletion to extra paths under an applicable prune: true target.
          10. Preserve unrelated files outside declared target roots.

          Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

          Skills as the First Consumer

          Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

          Before fleet rollout, verify that every skill is safe when discovered downstream:

          • Hub-context-only skills clearly prevent activation from the wrong context.
          • Skills do not assume .agents/skills/ exists downstream.
          • Sibling skill routing uses skill names or distribution-relative language.
          • Bundled references and scripts travel with their parent skill.
          • References to repository rules resolve through carried repository documents.
          • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

          The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

          Standup, Resync, and Audit Integration

          • Standup applies required tree declarations when establishing a repository baseline.
          • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
          • Audit classifies an absent tree as missing baseline and a stale tree as drift.
          • Audit compares downstream ground-truth branches against fetched hub main.
          • Retired tree content is removed only through the declaration's explicit prune authority.
          • The registry and applicability model decide which repositories receive each tree.

          Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

          CI and Freshness

          Separate integrity from fleet freshness.

          A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

          Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

          Use one or more of these mechanisms for freshness:

          • A scheduled or manually dispatched conformance check against current hub main.
          • Fleet audit from ProjectTemplate.
          • Propagation pull requests opened when promoted carried content changes.

          If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

          Required Tests

          Test the carry engine against temporary hub and downstream trees. Cover at least:

          • A clean verbatim tree.
          • A missing target root.
          • A missing file.
          • A modified same-size file.
          • An extra file and extra directory under a pruned target.
          • A source addition.
          • A retired source path.
          • An empty source inventory whose target root must exist.
          • A source or target symlink.
          • A target outside the repository root.
          • An overlapping or conflicting declaration.
          • An inapplicable declaration selected by repository type.
          • A mismatched target origin or registry identity.
          • A dirty target carrying unrelated changes.
          • A failed source read that must not appear clean.
          • Idempotent apply followed by a clean check.
          • Preservation of unrelated paths outside the declared target.

          Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

          Acceptance Criteria

          • .agents/skills/ remains the only hand-authored skill source.
          • ProjectTemplate generates the complete .github/skills/ distribution.
          • A generic manifest declaration owns the downstream .github/skills/ tree.
          • The carry tool provides deterministic check and apply modes.
          • Standup and resync use the carry tool rather than manual copying.
          • Audit detects absent, stale, modified, and extra downstream skill content.
          • Retiring a canonical skill removes it through explicit prune semantics.
          • Downstream repositories contain every skill path their Copilot bootstrap names.
          • Host-global skill installation continues unchanged.
          • Required CI checks prove integrity without depending on moving hub main.
          • A scheduled, audit, or propagation path reports fleet freshness.
          • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

          Relationship to #793 and PR #799

          #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

          This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            agentsAgents instructionsskillsAgent skill

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
              Skip to content

              Add Manifest-Driven Verbatim Tree Propagation #797

              Description

              @ptr727

              Summary

              Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

              The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

              Root Cause

              GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

              ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

              The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

              Architecture

              Keep these responsibilities separate:

              • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
              • scripts/skills_install.py installs hub skills for local agents on a host.
              • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
              • spec/audit.py measures downstream fidelity against promoted hub main.
              • Standup and resync decide when the carry tool applies changes.

              The data flow is:

              .agents/skills/
              |
              +-- build_dist.py --> .github/skills/
              | |
              | +-- carry tool --> downstream .github/skills/
              |
              +-- skills_install.py --> host-global agent installations
              

              Manifest Model

              Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

              {
              "source": ".github/skills",
              "target": ".github/skills",
              "fidelity": "verbatim-tree",
              "appliesTo": "*",
              "include": ["**/*"],
              "prune": true
              }

              The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

              verbatim-tree means:

              • Every included source file exists at the corresponding target path.
              • File bytes match after only the normalization explicitly allowed by the fidelity model.
              • No undeclared file or directory exists under a prune: true target.
              • A source addition becomes required downstream.
              • A retired source path is removed downstream.
              • The target root exists even when the resolved source inventory is empty.

              Reject overlapping declarations whose ownership or prune boundaries conflict.

              Carry Tool Interface

              Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

              python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
              python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

              check must report:

              • The hub commit used as canonical input.
              • The resolved repository name, types, and applicable declarations.
              • Missing target files and directories.
              • Modified target files.
              • Extra paths inside pruned targets.
              • Source and target digests for each declared tree.
              • An unreadable or unsafe state as undecided or failed, never clean.

              apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

              Write Safety

              Before applying changes, the tool must:

              1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
              2. Resolve the named repository through registry/repos.json.
              3. Confirm the target origin matches the registry entry.
              4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
              5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
              6. Refuse unrelated target changes instead of overwriting or bundling them.
              7. Resolve every source and target beneath its declared root before writing.
              8. Reject symlinks in either tree rather than following them.
              9. Restrict deletion to extra paths under an applicable prune: true target.
              10. Preserve unrelated files outside declared target roots.

              Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

              Skills as the First Consumer

              Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

              Before fleet rollout, verify that every skill is safe when discovered downstream:

              • Hub-context-only skills clearly prevent activation from the wrong context.
              • Skills do not assume .agents/skills/ exists downstream.
              • Sibling skill routing uses skill names or distribution-relative language.
              • Bundled references and scripts travel with their parent skill.
              • References to repository rules resolve through carried repository documents.
              • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

              The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

              Standup, Resync, and Audit Integration

              • Standup applies required tree declarations when establishing a repository baseline.
              • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
              • Audit classifies an absent tree as missing baseline and a stale tree as drift.
              • Audit compares downstream ground-truth branches against fetched hub main.
              • Retired tree content is removed only through the declaration's explicit prune authority.
              • The registry and applicability model decide which repositories receive each tree.

              Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

              CI and Freshness

              Separate integrity from fleet freshness.

              A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

              Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

              Use one or more of these mechanisms for freshness:

              • A scheduled or manually dispatched conformance check against current hub main.
              • Fleet audit from ProjectTemplate.
              • Propagation pull requests opened when promoted carried content changes.

              If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

              Required Tests

              Test the carry engine against temporary hub and downstream trees. Cover at least:

              • A clean verbatim tree.
              • A missing target root.
              • A missing file.
              • A modified same-size file.
              • An extra file and extra directory under a pruned target.
              • A source addition.
              • A retired source path.
              • An empty source inventory whose target root must exist.
              • A source or target symlink.
              • A target outside the repository root.
              • An overlapping or conflicting declaration.
              • An inapplicable declaration selected by repository type.
              • A mismatched target origin or registry identity.
              • A dirty target carrying unrelated changes.
              • A failed source read that must not appear clean.
              • Idempotent apply followed by a clean check.
              • Preservation of unrelated paths outside the declared target.

              Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

              Acceptance Criteria

              • .agents/skills/ remains the only hand-authored skill source.
              • ProjectTemplate generates the complete .github/skills/ distribution.
              • A generic manifest declaration owns the downstream .github/skills/ tree.
              • The carry tool provides deterministic check and apply modes.
              • Standup and resync use the carry tool rather than manual copying.
              • Audit detects absent, stale, modified, and extra downstream skill content.
              • Retiring a canonical skill removes it through explicit prune semantics.
              • Downstream repositories contain every skill path their Copilot bootstrap names.
              • Host-global skill installation continues unchanged.
              • Required CI checks prove integrity without depending on moving hub main.
              • A scheduled, audit, or propagation path reports fleet freshness.
              • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

              Relationship to #793 and PR #799

              #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

              This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                agentsAgents instructionsskillsAgent skill

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
                  Skip to content

                  Add Manifest-Driven Verbatim Tree Propagation #797

                  Description

                  @ptr727

                  Summary

                  Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

                  The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

                  Root Cause

                  GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

                  ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

                  The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

                  Architecture

                  Keep these responsibilities separate:

                  • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
                  • scripts/skills_install.py installs hub skills for local agents on a host.
                  • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
                  • spec/audit.py measures downstream fidelity against promoted hub main.
                  • Standup and resync decide when the carry tool applies changes.

                  The data flow is:

                  .agents/skills/
                  |
                  +-- build_dist.py --> .github/skills/
                  | |
                  | +-- carry tool --> downstream .github/skills/
                  |
                  +-- skills_install.py --> host-global agent installations
                  

                  Manifest Model

                  Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

                  {
                  "source": ".github/skills",
                  "target": ".github/skills",
                  "fidelity": "verbatim-tree",
                  "appliesTo": "*",
                  "include": ["**/*"],
                  "prune": true
                  }

                  The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

                  verbatim-tree means:

                  • Every included source file exists at the corresponding target path.
                  • File bytes match after only the normalization explicitly allowed by the fidelity model.
                  • No undeclared file or directory exists under a prune: true target.
                  • A source addition becomes required downstream.
                  • A retired source path is removed downstream.
                  • The target root exists even when the resolved source inventory is empty.

                  Reject overlapping declarations whose ownership or prune boundaries conflict.

                  Carry Tool Interface

                  Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

                  python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
                  python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

                  check must report:

                  • The hub commit used as canonical input.
                  • The resolved repository name, types, and applicable declarations.
                  • Missing target files and directories.
                  • Modified target files.
                  • Extra paths inside pruned targets.
                  • Source and target digests for each declared tree.
                  • An unreadable or unsafe state as undecided or failed, never clean.

                  apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

                  Write Safety

                  Before applying changes, the tool must:

                  1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
                  2. Resolve the named repository through registry/repos.json.
                  3. Confirm the target origin matches the registry entry.
                  4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
                  5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
                  6. Refuse unrelated target changes instead of overwriting or bundling them.
                  7. Resolve every source and target beneath its declared root before writing.
                  8. Reject symlinks in either tree rather than following them.
                  9. Restrict deletion to extra paths under an applicable prune: true target.
                  10. Preserve unrelated files outside declared target roots.

                  Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

                  Skills as the First Consumer

                  Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

                  Before fleet rollout, verify that every skill is safe when discovered downstream:

                  • Hub-context-only skills clearly prevent activation from the wrong context.
                  • Skills do not assume .agents/skills/ exists downstream.
                  • Sibling skill routing uses skill names or distribution-relative language.
                  • Bundled references and scripts travel with their parent skill.
                  • References to repository rules resolve through carried repository documents.
                  • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

                  The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

                  Standup, Resync, and Audit Integration

                  • Standup applies required tree declarations when establishing a repository baseline.
                  • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
                  • Audit classifies an absent tree as missing baseline and a stale tree as drift.
                  • Audit compares downstream ground-truth branches against fetched hub main.
                  • Retired tree content is removed only through the declaration's explicit prune authority.
                  • The registry and applicability model decide which repositories receive each tree.

                  Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

                  CI and Freshness

                  Separate integrity from fleet freshness.

                  A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

                  Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

                  Use one or more of these mechanisms for freshness:

                  • A scheduled or manually dispatched conformance check against current hub main.
                  • Fleet audit from ProjectTemplate.
                  • Propagation pull requests opened when promoted carried content changes.

                  If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

                  Required Tests

                  Test the carry engine against temporary hub and downstream trees. Cover at least:

                  • A clean verbatim tree.
                  • A missing target root.
                  • A missing file.
                  • A modified same-size file.
                  • An extra file and extra directory under a pruned target.
                  • A source addition.
                  • A retired source path.
                  • An empty source inventory whose target root must exist.
                  • A source or target symlink.
                  • A target outside the repository root.
                  • An overlapping or conflicting declaration.
                  • An inapplicable declaration selected by repository type.
                  • A mismatched target origin or registry identity.
                  • A dirty target carrying unrelated changes.
                  • A failed source read that must not appear clean.
                  • Idempotent apply followed by a clean check.
                  • Preservation of unrelated paths outside the declared target.

                  Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

                  Acceptance Criteria

                  • .agents/skills/ remains the only hand-authored skill source.
                  • ProjectTemplate generates the complete .github/skills/ distribution.
                  • A generic manifest declaration owns the downstream .github/skills/ tree.
                  • The carry tool provides deterministic check and apply modes.
                  • Standup and resync use the carry tool rather than manual copying.
                  • Audit detects absent, stale, modified, and extra downstream skill content.
                  • Retiring a canonical skill removes it through explicit prune semantics.
                  • Downstream repositories contain every skill path their Copilot bootstrap names.
                  • Host-global skill installation continues unchanged.
                  • Required CI checks prove integrity without depending on moving hub main.
                  • A scheduled, audit, or propagation path reports fleet freshness.
                  • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

                  Relationship to #793 and PR #799

                  #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

                  This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    agentsAgents instructionsskillsAgent skill

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
                      Skip to content

                      Add Manifest-Driven Verbatim Tree Propagation #797

                      Description

                      @ptr727

                      Summary

                      Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

                      The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

                      Root Cause

                      GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

                      ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

                      The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

                      Architecture

                      Keep these responsibilities separate:

                      • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
                      • scripts/skills_install.py installs hub skills for local agents on a host.
                      • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
                      • spec/audit.py measures downstream fidelity against promoted hub main.
                      • Standup and resync decide when the carry tool applies changes.

                      The data flow is:

                      .agents/skills/
                      |
                      +-- build_dist.py --> .github/skills/
                      | |
                      | +-- carry tool --> downstream .github/skills/
                      |
                      +-- skills_install.py --> host-global agent installations
                      

                      Manifest Model

                      Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

                      {
                      "source": ".github/skills",
                      "target": ".github/skills",
                      "fidelity": "verbatim-tree",
                      "appliesTo": "*",
                      "include": ["**/*"],
                      "prune": true
                      }

                      The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

                      verbatim-tree means:

                      • Every included source file exists at the corresponding target path.
                      • File bytes match after only the normalization explicitly allowed by the fidelity model.
                      • No undeclared file or directory exists under a prune: true target.
                      • A source addition becomes required downstream.
                      • A retired source path is removed downstream.
                      • The target root exists even when the resolved source inventory is empty.

                      Reject overlapping declarations whose ownership or prune boundaries conflict.

                      Carry Tool Interface

                      Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

                      python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
                      python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

                      check must report:

                      • The hub commit used as canonical input.
                      • The resolved repository name, types, and applicable declarations.
                      • Missing target files and directories.
                      • Modified target files.
                      • Extra paths inside pruned targets.
                      • Source and target digests for each declared tree.
                      • An unreadable or unsafe state as undecided or failed, never clean.

                      apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

                      Write Safety

                      Before applying changes, the tool must:

                      1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
                      2. Resolve the named repository through registry/repos.json.
                      3. Confirm the target origin matches the registry entry.
                      4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
                      5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
                      6. Refuse unrelated target changes instead of overwriting or bundling them.
                      7. Resolve every source and target beneath its declared root before writing.
                      8. Reject symlinks in either tree rather than following them.
                      9. Restrict deletion to extra paths under an applicable prune: true target.
                      10. Preserve unrelated files outside declared target roots.

                      Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

                      Skills as the First Consumer

                      Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

                      Before fleet rollout, verify that every skill is safe when discovered downstream:

                      • Hub-context-only skills clearly prevent activation from the wrong context.
                      • Skills do not assume .agents/skills/ exists downstream.
                      • Sibling skill routing uses skill names or distribution-relative language.
                      • Bundled references and scripts travel with their parent skill.
                      • References to repository rules resolve through carried repository documents.
                      • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

                      The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

                      Standup, Resync, and Audit Integration

                      • Standup applies required tree declarations when establishing a repository baseline.
                      • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
                      • Audit classifies an absent tree as missing baseline and a stale tree as drift.
                      • Audit compares downstream ground-truth branches against fetched hub main.
                      • Retired tree content is removed only through the declaration's explicit prune authority.
                      • The registry and applicability model decide which repositories receive each tree.

                      Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

                      CI and Freshness

                      Separate integrity from fleet freshness.

                      A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

                      Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

                      Use one or more of these mechanisms for freshness:

                      • A scheduled or manually dispatched conformance check against current hub main.
                      • Fleet audit from ProjectTemplate.
                      • Propagation pull requests opened when promoted carried content changes.

                      If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

                      Required Tests

                      Test the carry engine against temporary hub and downstream trees. Cover at least:

                      • A clean verbatim tree.
                      • A missing target root.
                      • A missing file.
                      • A modified same-size file.
                      • An extra file and extra directory under a pruned target.
                      • A source addition.
                      • A retired source path.
                      • An empty source inventory whose target root must exist.
                      • A source or target symlink.
                      • A target outside the repository root.
                      • An overlapping or conflicting declaration.
                      • An inapplicable declaration selected by repository type.
                      • A mismatched target origin or registry identity.
                      • A dirty target carrying unrelated changes.
                      • A failed source read that must not appear clean.
                      • Idempotent apply followed by a clean check.
                      • Preservation of unrelated paths outside the declared target.

                      Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

                      Acceptance Criteria

                      • .agents/skills/ remains the only hand-authored skill source.
                      • ProjectTemplate generates the complete .github/skills/ distribution.
                      • A generic manifest declaration owns the downstream .github/skills/ tree.
                      • The carry tool provides deterministic check and apply modes.
                      • Standup and resync use the carry tool rather than manual copying.
                      • Audit detects absent, stale, modified, and extra downstream skill content.
                      • Retiring a canonical skill removes it through explicit prune semantics.
                      • Downstream repositories contain every skill path their Copilot bootstrap names.
                      • Host-global skill installation continues unchanged.
                      • Required CI checks prove integrity without depending on moving hub main.
                      • A scheduled, audit, or propagation path reports fleet freshness.
                      • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

                      Relationship to #793 and PR #799

                      #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

                      This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        agentsAgents instructionsskillsAgent skill

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
                          Skip to content

                          Add Manifest-Driven Verbatim Tree Propagation #797

                          Description

                          @ptr727

                          Summary

                          Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

                          The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

                          Root Cause

                          GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

                          ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

                          The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

                          Architecture

                          Keep these responsibilities separate:

                          • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
                          • scripts/skills_install.py installs hub skills for local agents on a host.
                          • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
                          • spec/audit.py measures downstream fidelity against promoted hub main.
                          • Standup and resync decide when the carry tool applies changes.

                          The data flow is:

                          .agents/skills/
                          |
                          +-- build_dist.py --> .github/skills/
                          | |
                          | +-- carry tool --> downstream .github/skills/
                          |
                          +-- skills_install.py --> host-global agent installations
                          

                          Manifest Model

                          Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

                          {
                          "source": ".github/skills",
                          "target": ".github/skills",
                          "fidelity": "verbatim-tree",
                          "appliesTo": "*",
                          "include": ["**/*"],
                          "prune": true
                          }

                          The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

                          verbatim-tree means:

                          • Every included source file exists at the corresponding target path.
                          • File bytes match after only the normalization explicitly allowed by the fidelity model.
                          • No undeclared file or directory exists under a prune: true target.
                          • A source addition becomes required downstream.
                          • A retired source path is removed downstream.
                          • The target root exists even when the resolved source inventory is empty.

                          Reject overlapping declarations whose ownership or prune boundaries conflict.

                          Carry Tool Interface

                          Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

                          python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
                          python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

                          check must report:

                          • The hub commit used as canonical input.
                          • The resolved repository name, types, and applicable declarations.
                          • Missing target files and directories.
                          • Modified target files.
                          • Extra paths inside pruned targets.
                          • Source and target digests for each declared tree.
                          • An unreadable or unsafe state as undecided or failed, never clean.

                          apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

                          Write Safety

                          Before applying changes, the tool must:

                          1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
                          2. Resolve the named repository through registry/repos.json.
                          3. Confirm the target origin matches the registry entry.
                          4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
                          5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
                          6. Refuse unrelated target changes instead of overwriting or bundling them.
                          7. Resolve every source and target beneath its declared root before writing.
                          8. Reject symlinks in either tree rather than following them.
                          9. Restrict deletion to extra paths under an applicable prune: true target.
                          10. Preserve unrelated files outside declared target roots.

                          Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

                          Skills as the First Consumer

                          Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

                          Before fleet rollout, verify that every skill is safe when discovered downstream:

                          • Hub-context-only skills clearly prevent activation from the wrong context.
                          • Skills do not assume .agents/skills/ exists downstream.
                          • Sibling skill routing uses skill names or distribution-relative language.
                          • Bundled references and scripts travel with their parent skill.
                          • References to repository rules resolve through carried repository documents.
                          • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

                          The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

                          Standup, Resync, and Audit Integration

                          • Standup applies required tree declarations when establishing a repository baseline.
                          • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
                          • Audit classifies an absent tree as missing baseline and a stale tree as drift.
                          • Audit compares downstream ground-truth branches against fetched hub main.
                          • Retired tree content is removed only through the declaration's explicit prune authority.
                          • The registry and applicability model decide which repositories receive each tree.

                          Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

                          CI and Freshness

                          Separate integrity from fleet freshness.

                          A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

                          Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

                          Use one or more of these mechanisms for freshness:

                          • A scheduled or manually dispatched conformance check against current hub main.
                          • Fleet audit from ProjectTemplate.
                          • Propagation pull requests opened when promoted carried content changes.

                          If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

                          Required Tests

                          Test the carry engine against temporary hub and downstream trees. Cover at least:

                          • A clean verbatim tree.
                          • A missing target root.
                          • A missing file.
                          • A modified same-size file.
                          • An extra file and extra directory under a pruned target.
                          • A source addition.
                          • A retired source path.
                          • An empty source inventory whose target root must exist.
                          • A source or target symlink.
                          • A target outside the repository root.
                          • An overlapping or conflicting declaration.
                          • An inapplicable declaration selected by repository type.
                          • A mismatched target origin or registry identity.
                          • A dirty target carrying unrelated changes.
                          • A failed source read that must not appear clean.
                          • Idempotent apply followed by a clean check.
                          • Preservation of unrelated paths outside the declared target.

                          Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

                          Acceptance Criteria

                          • .agents/skills/ remains the only hand-authored skill source.
                          • ProjectTemplate generates the complete .github/skills/ distribution.
                          • A generic manifest declaration owns the downstream .github/skills/ tree.
                          • The carry tool provides deterministic check and apply modes.
                          • Standup and resync use the carry tool rather than manual copying.
                          • Audit detects absent, stale, modified, and extra downstream skill content.
                          • Retiring a canonical skill removes it through explicit prune semantics.
                          • Downstream repositories contain every skill path their Copilot bootstrap names.
                          • Host-global skill installation continues unchanged.
                          • Required CI checks prove integrity without depending on moving hub main.
                          • A scheduled, audit, or propagation path reports fleet freshness.
                          • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

                          Relationship to #793 and PR #799

                          #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

                          This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            agentsAgents instructionsskillsAgent skill

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add Manifest-Driven Verbatim Tree Propagation · Issue #797 · ptr727/ProjectTemplate · GitHub
                              Skip to content

                              Add Manifest-Driven Verbatim Tree Propagation #797

                              Description

                              @ptr727

                              Summary

                              Add a manifest-driven carry engine for wholesale hub content. Use the generated .github/skills/ tree as its first consumer.

                              The engine must copy declared content from a fetched ProjectTemplate checkout into a registered downstream worktree. It must also detect missing, modified, and extra downstream content.

                              Root Cause

                              GitHub Copilot code review reads skills from the pull request head branch. It cannot see skills installed on a maintainer's host or stored only in another repository.

                              ProjectTemplate keeps .agents/skills/ as its only hand-authored skill source. scripts/build_dist.py generates the complete .github/skills/ and Claude plugin distributions. Downstream repositories still need the GitHub distribution inside their own trees.

                              The fleet already declares carried files, applicability, and fidelity in spec/files.json. A generic tree carry extends that model without creating a skills-only propagation mechanism.

                              Architecture

                              Keep these responsibilities separate:

                              • scripts/build_dist.py transforms canonical skill sources into provider distributions inside ProjectTemplate.
                              • scripts/skills_install.py installs hub skills for local agents on a host.
                              • A new hub-hosted carry tool copies declared artifacts into downstream repository worktrees.
                              • spec/audit.py measures downstream fidelity against promoted hub main.
                              • Standup and resync decide when the carry tool applies changes.

                              The data flow is:

                              .agents/skills/
                              |
                              +-- build_dist.py --> .github/skills/
                              | |
                              | +-- carry tool --> downstream .github/skills/
                              |
                              +-- skills_install.py --> host-global agent installations
                              

                              Manifest Model

                              Extend the fleet file specification with a whole-tree declaration. The final field names may follow the existing schema conventions, but the declaration must express this intent:

                              {
                              "source": ".github/skills",
                              "target": ".github/skills",
                              "fidelity": "verbatim-tree",
                              "appliesTo": "*",
                              "include": ["**/*"],
                              "prune": true
                              }

                              The model must support future wholesale hub content without embedding skill-specific behavior in the engine.

                              verbatim-tree means:

                              • Every included source file exists at the corresponding target path.
                              • File bytes match after only the normalization explicitly allowed by the fidelity model.
                              • No undeclared file or directory exists under a prune: true target.
                              • A source addition becomes required downstream.
                              • A retired source path is removed downstream.
                              • The target root exists even when the resolved source inventory is empty.

                              Reject overlapping declarations whose ownership or prune boundaries conflict.

                              Carry Tool Interface

                              Provide read-only and mutating modes from a hub checkout. The exact script name may follow repository naming conventions.

                              python3 scripts/carry.py check PhotoCleaner --target /path/to/worktree
                              python3 scripts/carry.py apply PhotoCleaner --target /path/to/worktree

                              check must report:

                              • The hub commit used as canonical input.
                              • The resolved repository name, types, and applicable declarations.
                              • Missing target files and directories.
                              • Modified target files.
                              • Extra paths inside pruned targets.
                              • Source and target digests for each declared tree.
                              • An unreadable or unsafe state as undecided or failed, never clean.

                              apply must print every path it creates, replaces, or removes. It must finish by running the same comparison used by check.

                              Write Safety

                              Before applying changes, the tool must:

                              1. Confirm it runs from a ProjectTemplate checkout fetched immediately before use.
                              2. Resolve the named repository through registry/repos.json.
                              3. Confirm the target origin matches the registry entry.
                              4. Confirm the target is not ProjectTemplate itself unless a declaration explicitly permits that case.
                              5. Confirm the target is an isolated feature-branch worktree based on the correct development branch.
                              6. Refuse unrelated target changes instead of overwriting or bundling them.
                              7. Resolve every source and target beneath its declared root before writing.
                              8. Reject symlinks in either tree rather than following them.
                              9. Restrict deletion to extra paths under an applicable prune: true target.
                              10. Preserve unrelated files outside declared target roots.

                              Use recoverable operations where practical. Never turn a failed read or comparison into an empty inventory.

                              Skills as the First Consumer

                              Carry the complete generated .github/skills/ distribution initially. Do not maintain a second manual allowlist.

                              Before fleet rollout, verify that every skill is safe when discovered downstream:

                              • Hub-context-only skills clearly prevent activation from the wrong context.
                              • Skills do not assume .agents/skills/ exists downstream.
                              • Sibling skill routing uses skill names or distribution-relative language.
                              • Bundled references and scripts travel with their parent skill.
                              • References to repository rules resolve through carried repository documents.
                              • Commands that require ProjectTemplate explicitly say to run from a separate hub checkout.

                              The carried .github/copilot-instructions.md must name only skill paths present in the same downstream head tree.

                              Standup, Resync, and Audit Integration

                              • Standup applies required tree declarations when establishing a repository baseline.
                              • Resync runs check, reads every modified-file diff, and applies the carry in procedure order.
                              • Audit classifies an absent tree as missing baseline and a stale tree as drift.
                              • Audit compares downstream ground-truth branches against fetched hub main.
                              • Retired tree content is removed only through the declaration's explicit prune authority.
                              • The registry and applicability model decide which repositories receive each tree.

                              Do not use the carried-instruction-file overwrite guard for a fully owned verbatim-tree. Apply an equivalent local-addition safeguard by reporting every extra path before pruning it.

                              CI and Freshness

                              Separate integrity from fleet freshness.

                              A required downstream pull request check may verify that the carried tree matches its recorded hub source commit. This proves the tree was not hand-modified.

                              Do not make unrelated downstream pull requests compare against the moving tip of hub main. A new hub commit must not break every open downstream pull request.

                              Use one or more of these mechanisms for freshness:

                              • A scheduled or manually dispatched conformance check against current hub main.
                              • Fleet audit from ProjectTemplate.
                              • Propagation pull requests opened when promoted carried content changes.

                              If a source stamp is used, it must identify the hub repository and exact commit. A stamp is evidence of provenance, not proof that the commit is current.

                              Required Tests

                              Test the carry engine against temporary hub and downstream trees. Cover at least:

                              • A clean verbatim tree.
                              • A missing target root.
                              • A missing file.
                              • A modified same-size file.
                              • An extra file and extra directory under a pruned target.
                              • A source addition.
                              • A retired source path.
                              • An empty source inventory whose target root must exist.
                              • A source or target symlink.
                              • A target outside the repository root.
                              • An overlapping or conflicting declaration.
                              • An inapplicable declaration selected by repository type.
                              • A mismatched target origin or registry identity.
                              • A dirty target carrying unrelated changes.
                              • A failed source read that must not appear clean.
                              • Idempotent apply followed by a clean check.
                              • Preservation of unrelated paths outside the declared target.

                              Add an integration fixture proving that every skill path named by downstream Copilot instructions exists in the resolved carried tree.

                              Acceptance Criteria

                              • .agents/skills/ remains the only hand-authored skill source.
                              • ProjectTemplate generates the complete .github/skills/ distribution.
                              • A generic manifest declaration owns the downstream .github/skills/ tree.
                              • The carry tool provides deterministic check and apply modes.
                              • Standup and resync use the carry tool rather than manual copying.
                              • Audit detects absent, stale, modified, and extra downstream skill content.
                              • Retiring a canonical skill removes it through explicit prune semantics.
                              • Downstream repositories contain every skill path their Copilot bootstrap names.
                              • Host-global skill installation continues unchanged.
                              • Required CI checks prove integrity without depending on moving hub main.
                              • A scheduled, audit, or propagation path reports fleet freshness.
                              • Documentation identifies the canonical source, generated artifacts, carried destinations, and ownership boundaries.

                              Relationship to #793 and PR #799

                              #793 defines the review behavior and output contract. PR #799 generates the complete Copilot-facing skill distribution in ProjectTemplate.

                              This issue owns the generic downstream carry mechanism and its first rollout for .github/skills/.

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                agentsAgents instructionsskillsAgent skill

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions