Skip to content

feat(app-control): add the control-skill Mask contract and publishable set #11387

Description

@kyle-sexton

Parent

Refs #8651. Evidence-verification plan: Brief and acceptance criteria at #11364 (comment); Design and Plan comments are on #11364.

Depends on

Outcome

Control skills declare a ## Mask, drive post-checks every sidecar and publishable text file against it, and only masked, scanned files reach the publishable list and report.public.{json,md}.

Demo: run drive's evals and check-map.test.sh; the wrapped-email, runtime-value and planted-report cases pass.

Plan (phase S3)

Satisfies: AC8, AC4
Size Medium. Depends on: S1 (#11384) (same files). Plugin: app-control. Design: Contracts C2, C3.

  • reference/control-skill.md: ## Mask section in the Hub table; <artifact>.txt sidecar rule in "Writing the Capture section"; <changed files> placeholder in Environments.
  • The post-check is independent of the masks: the control skill names literal values to look for at run time (a ## Mask values: line naming config fields or commands that print them, e.g. the signed-in email and org), plus a generic credential pattern; drive scans sidecars and every publishable text file (report.public.*, e2e-summary.json is the consumer's to scan, S2a) with line wraps joined and box-drawing characters stripped.
  • drive/SKILL.md Evidence + reference/evidence.md: sidecar scan, artifacts[].mask, publishable, capture_count, report.public.{json,md}; raw and secrets_mark entries never publishable.
  • map check reports a hub with image/video Capture and no ## Mask line (skills/map/scripts/check-map.sh + test).
  • Sanity Check: drive evals "email wrapped across two rows → publishable false", "org name from runtime values → publishable false", "planted email in report text → report.public not publishable" pass; bash plugins/app-control/skills/map/scripts/check-map.test.sh exits 0; grep -c "publishable" plugins/app-control/skills/drive/reference/evidence.md ≥ 2.
  • Run budget: at most 2 runs per new eval case; stop on the first usage-limit error.

Design excerpt

  • app-control (owns finding and driving apps): drive gains affected (diff → features, backed
    by scripts/affected_features.py), --trusted-root <dir>, the mask post-check, the publishable
    list and redacted report.public.{json,md}; the control-skill contract (reference/control-skill.md)
    gains ## Mask and the <changed files> placeholder. Knows nothing about Claude Code.
components:
  schemas:
    MaskSection:             # C2, control skill hub "## Mask" (markdown, shown as data)
      oneOf:
        - type: array        # lines "- <label> | <regex>"
          items: {type: object, required: [label, pattern], properties: {label: {type: string}, pattern: {type: string}}}
        - type: string       # "none: <reason>"
    ReportJsonAdditions:     # C3, added to drive report.json (evidence.md table)
      type: object
      properties:
        trusted_root: {type: [string, "null"]}
        affected: {type: array, items: {type: string}}
        capture_count: {type: integer}
        publishable: {type: array, items: {type: string}}   # paths safe to upload
        artifacts:
          type: array
          items:
            type: object
            properties:
              path: {type: string}
              kind: {type: string}
              mask: {enum: [applied, none-declared, not-checked, hit]}
              publishable: {type: boolean}
  • Control skill ## Mask: image/video Capture commands apply it and write <artifact>.txt; drive
    scans sidecars; a hit, a missing sidecar, or no ## Mask line → not publishable. Raw captures and
    secrets_mark entries never publishable.

Acceptance criteria

Brief criteria this slice satisfies:

  • AC8: A passing PR carries one comment linking redacted evidence; account and usage lines never appear in uploaded captures.
  • AC4: With the app's control skill not installed, drive falls back to the generic recipe and the report says so; nothing errors.

Done when:

  • Sanity Check passes: drive evals "email wrapped across two rows → publishable false", "org name from runtime values → publishable false", "planted email in report text → report.public not publishable" pass; bash plugins/app-control/skills/map/scripts/check-map.test.sh exits 0; grep -c "publishable" plugins/app-control/skills/drive/reference/evidence.md ≥ 2.
  • Raw captures and secrets_mark entries are never publishable
  • A hit, a missing sidecar, or no ## Mask line makes an artifact not publishable (fail closed)
  • The plugin's version and CHANGELOG are bumped per the repository's release convention
  • ci-status is green on the PR head

Owner decision Q12 (2026-10-30)

Q12 answered by the owner: approved evidence is attached to the PR with gh pr comment --attach, in collapsed sections. Video is therefore publishable, under the same masking rule as stills: a capture is publishable only when every frame passes the mask check (for example a region mask the control skill declares); a capture not proven clean is never attached.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UJUn7KoThXoYQoxfvdCVi7

Activity

  1. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    on Oct 30, 2026
  2. github-actions commented on Oct 30, 2026

    @github-actions
    Contributor

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

    Size: Medium
    Complexity: Medium
    Uncertainty: Known
    Flags: none
    Blocked by: #11384

    Understood: add the ## Mask contract to the app-control control-skill reference. Drive would then scan sidecars and publishable text files against it and fail closed. Only masked, scanned files would reach publishable and report.public.{json,md}. The map check would also flag a hub with image/video Capture and no ## Mask line. The issue gives its done-when items and sanity checks. The video-upload rule is held for a separate owner decision (Q12) and is outside this slice. No likely duplicates found. It depends on #11384, which is still open.

    Automated triage, applied by the lanes App.

  3. melodic-automation-lanes commented on Oct 30, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane yet: blocker #11384 is not closed by a listed human or a merge.

  4. github-actions commented on Oct 31, 2026

    @github-actions
    Contributor
    No description provided.
  5. github-actions commented on Oct 31, 2026

    @github-actions
    Contributor
    No description provided.
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

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.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.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions