Skip to content

pr-pipeline: give fix-docs a docs-only patch row #8956

Open

Description

@kyle-sexton

Problem

fix-docs (pr-refine, Phase 7.1) passes no patch-prepare, so apply-patch uses patch-rules.json's default row. That row allows any path its refusal list doesn't name. fix-docs only ever needs to change markdown, so its patch can carry more than the lane needs.

Proposed fix

  • Add a docs row to .github/actions/resolve-config/patch-rules.json that allows only **/*.md and refuses skills/** and any SKILL.md.
  • Pass patch-prepare: docs from pr-refine.yml's apply-patch job.
  • Add apply-patch and caller tests: a non-markdown path is refused, and so is a SKILL.md.

Once this lands, web access for fix-docs can be reconsidered.

Context

Raised in the security review of Phase 7.1. Web access was removed from fix-docs in 7.1, which closes the immediate risk; this narrows the lane further.

🤖 Generated with Claude Code

Activity

  1. github-actions commented on Oct 22, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: fix-docs currently falls back to the default row in patch-rules.json, which allows more paths than a markdown-only lane needs. The proposal is a docs row (allow **/*.md; refuse skills/** and SKILL.md), patch-prepare: docs in pr-refine.yml's apply-patch job, and tests for the refused paths. The issue is specific enough to act on. I found no likely duplicates.

    Automated triage, applied by the lanes App.

  2. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 22, 2026
  3. removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 25, 2026
  4. kyle-sexton commented on Oct 25, 2026

    @kyle-sexton
    MemberAuthor

    Released for re-triage under the owner's 2026-10-24 rule: an issue stops for a person only for an intent or vision question, a security call, a host or attended run, or spend outside prepaid credit. The hold label came off and intake triage runs again now; it re-applies a hold, with a numbered question, when one of those applies.

    To hold this issue again, add needs-human (or status: needs-decision) and say why in a comment.

  5. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 25, 2026
  6. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    status: needs-decisionAwaiting a human or maintainer judgment call.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Oct 25, 2026
  7. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed - [ ] criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  8. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: admission moved the issue to status: needs-decision; its comment says why.

  9. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: fix-docs's apply-docs-patch job uses a new docs row in patch-rules.json that admits only Markdown paths and refuses skills/** and any SKILL.md, with tests covering the refusals.

    Acceptance criteria

    • patch-rules.json has a docs row with the universal refuse list plus new refusals for skills/** and any SKILL.md (any case, any depth), and an allow rule matching only **/*.md
    • patch-rules.schema.json lists the docs row under properties and the new allow and refuse names in their enums with descriptions, and the schema validates patch-rules.json
    • predicates.mjs implements the new markdown allow predicate; the refusals are implemented where apply-patch.mjs evaluates the named refusals
    • pr-refine.yml's apply-docs-patch job passes patch-prepare: docs, and the comment above that job no longer says it uses the default row
    • pr-run-activity-write.yml accepts docs as a patch-prepare value and its input doc lists it, if the input is validated or documented there
    • an apply-patch test shows a patch changing a non-markdown path (for example a .json or .mjs file) under the docs row is refused with patch-protected-path
    • an apply-patch test shows a patch touching skills/<name>/SKILL.md or any other SKILL.md under the docs row is refused, and a patch touching only a .md file outside skills/ is admitted
    • a callers.test.mjs assertion shows apply-docs-patch passes patch-prepare docs
    • docs/conventions/pr-pipeline/pr-run-activity.md (near line 1357) and the Patch rules section of README.md describe the docs row instead of the default row for fix-docs, and CHANGELOG.md gets an entry
    • the repository's resolve-config and apply-patch test suites pass

    Dependencies

    • none blocking; the follow-up to reconsider fix-docs web access is separate and waits on this landing

    Related work

    Sources read

    • .github/actions/resolve-config/patch-rules.json:53: the default row allows ["any"] with only the universal refusals; no docs row exists
    • .github/actions/resolve-config/patch-rules.schema.json:44: allow is an enum of any, kept-threads, dependency-manifests, merge-result, so a markdown-only rule needs a new predicate; refuse enum at :28 has no skills/SKILL.md names
    • .github/scripts/apply-patch/predicates.mjs:9: PREDICATES map where a new markdown predicate goes
    • .github/workflows/pr-refine.yml:225: the push job is named apply-docs-patch, not apply-patch, and passes no patch-prepare
    • docs/conventions/pr-pipeline/pr-run-activity.md:1357: documents fix-docs as taking the default row

    Automated refinement by the lanes App. Admission counts only criteria a listed human wrote: to confirm these, post them as your own comment whose first line is **Decision recorded.**, which sends the issue back through intake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: lowNice-to-have, cosmetic, or speculative; opportunistic.status: needs-decisionAwaiting a human or maintainer judgment call.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions