configure-surface

v2026.09.24

Surface doc-drift gate: scaffold surf.toml + hubs, wire the SHA-pinned pre-commit/Action. Use when adding a docs-governed-like-code CI gate.

GitHub
安装命令
npx skhub add laurigates/configure-surface
Markdown
SKILL.md

/configure:surface

Scaffold and harden Surface — a deterministic "documentation governed like code" gate. Surface anchors prose claims to code symbols, stores an AST-normalized logic fingerprint per symbol, and blocks CI/commits when the fingerprint drifts until a human re-runs surf verify. It ignores cosmetic edits and catches flipped operators, relaxed comparisons, and dropped await.

⚠️ Experimental — adopt defensively. As of 2026-06 Surface is a young, single-maintainer project (no crates.io publish, bus-factor 1). The engine and release hygiene vetted well, but treat it as a pinned, optional gate — never an unpinned dependency. This skill defaults to SHA-pinned installs and fail-closed checksum verification.

When to Use This Skill

Use this skill when...Use another approach when...
Adding a deterministic doc↔code drift gate to CI/pre-commitEnforcing same-commit doc discipline by convention (blueprint:blueprint-docs-currency)
You want specific prose claims pinned to specific functionsDetecting stale generated content (blueprint:blueprint-sync)
You want an offline, no-LLM gate that fails the build on logic driftYou want semantic "is the doc still true?" judgment (code-quality:code-review)
Hardening an existing Surface setup (pin by SHA, verify checksums)Generating docs from code (documentation:docs-generate)

Context

  • surf.toml: !find . -maxdepth 2 -name 'surf.toml'
  • Hubs dir: !find . -maxdepth 2 -type d -name 'hubs'
  • Pre-commit config: !find . -maxdepth 1 -name '.pre-commit-config.yaml'
  • Workflows: !find . -path '*/.github/workflows/*' -maxdepth 3 -name '*.yml'
  • Language markers: !find . -maxdepth 1 \( -name 'Cargo.toml' -o -name 'package.json' -o -name 'pyproject.toml' -o -name 'go.mod' \)

Parameters

Parse from $ARGUMENTS:

  • --check-only: Report Surface adoption status and pin hygiene; make no changes (CI mode).
  • --fix: Apply scaffolding and hardening without prompting.
  • --pin <tag>: Release tag to install/pin (default: latest stable; resolve its commit SHA before writing any uses: ref).

Execution

Execute this Surface configuration workflow:

Step 1: Detect current state

From Context, classify the repo:

SignalMeaning
surf.toml presentSurface already initialised — go to hardening (Step 5)
Hubs dir present, no surf.tomlPartial setup — repair
NeitherGreenfield — full scaffold
Language markerSurface supports Rust, TypeScript/JS (TSX grammar), Python, Go. Warn if none match — anchors only resolve in supported languages.

If --check-only, report the table and the pin audit from Step 5, then stop.

Step 2: Confirm the maturity trade-off

Before writing files, surface the experimental posture (the blockquote above) and confirm with AskUserQuestion unless --fix is set: adopt as a pinned optional gate (recommended) or skip. Record the chosen pin tag.

Step 3: Resolve the pinned ref

Resolve the chosen tag to the commit SHA it points at so every uses: and rev: is reproducible — a release tag can be re-pointed to a different commit after the fact, so the SHA the tag resolved to (with the tag kept in a trailing comment) is the real immutable anchor:

git ls-remote https://github.com/Connorrmcd6/surface refs/tags/<tag>

Land the Action ref as Connorrmcd6/surface@<sha> # <tag> and the pre-commit rev: as <tag> (github-tags datasource — Renovate manages both; see .claude/rules/version-pinning.md). Do not hand-transcribe a SHA from memory.

Carry the same tag into the Action step's version: input (Step 5) — the ref pins the action, not the binary it installs.

Step 4: Scaffold (greenfield)

  1. Create surf.toml:
    hubs = ["hubs/*.md"]
    
  2. Create hubs/ with one starter hub anchoring a real, stable symbol the team relies on. Hub shape:
    ---
    summary: One-line description of what this hub governs.
    anchors:
      - claim: >
          The prose claim about behaviour that must stay true.
        at: src/path/file.ts > symbolName
        hash: ""   # surf verify seals this after you confirm the prose
    refs: []
    ---
    
    # Title
    
    Longer explanation a reviewer reads when the gate flags drift.
    
  3. Run surf lint (every anchor resolves to exactly one symbol), then surf verify to seal hashes.

Step 5: Wire + harden the gates

Pre-commit — add to .pre-commit-config.yaml (requires surf on PATH; pair with /configure:web-session to install it in Claude Code web sessions):

- repo: https://github.com/Connorrmcd6/surface
  rev: v0.8.0   # --pin tag; Renovate-managed (github-tags)
  hooks:
    - id: surf-lint   # anchors resolve
    - id: surf-check  # the gate — blocks on drift

GitHub Action — scaffold .github/workflows/ with a SHA-pinned ref and an explicit version::

name: "Docs: Surface drift gate"
on: [pull_request]
jobs:
  surface:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
      - uses: Connorrmcd6/surface@091b937ae34ac81a02386604fed977dd24f1f0cf # v0.8.0
        with:
          version: v0.8.0   # pins the BINARY; the input defaults to floating `latest`
          args: check

Two pins, not one. The @<sha> # vX.Y.Z ref pins the composite action and its bundled install.sh; version: pins the binary that installer downloads. Omit it and action.yml's own default (latest) resolves releases/latest over the API on every run — a new upstream release then changes gate behaviour with no local change, landing as a red merge gate nobody can attribute to an edit. Checksum verification does not close this: it proves the download matches its own published hash, not that it is the version you pinned. Keep the two values equal; Renovate bumps the ref, so update version: to match in the same PR.

The historical installer-pin gap (action.yml piping install.sh from mutable main) is fixed and shipped — v0.8.0 runs sh "${{ github.action_path }}/install.sh". Pinning v0.6.2 or earlier still carries that gap; vendor install.sh at that ref if you must stay there.

Step 6: Document the JSON → reviewer handoff

Surface keeps semantic judgment out of its deterministic core and emits JSON for reviewer plugins (surf check --format json). Note in the repo (e.g. CONTRIBUTING or the workflow) that a drift verdict can be handed to code-quality:code-review / verify to judge whether the claim is still true before a human runs surf verify. That is the division of labour Surface is designed for and where our skills add the most value.

Step 7: Report

Print: scaffold actions taken, the resolved pin (<sha> # <tag>), the version: input value, the pre-commit + Action wiring status, and the hardening checklist below with each item ✓/✗.

Hardening checklist

ControlTarget state
Action refSHA-pinned with # <tag> comment, not a floating major
Binary versionPinned via version: <tag> in with:, not left at the floating latest default
InstallerChecksum-verified (default) or vendored at the pinned ref
Pin freshnessrev: / uses: Renovate-visible (github-tags shape)
Gate scopesurf check --base <ref> to diff-scope to changed files in CI
FallbackmacOS Intel / Windows unsupported — document cargo install --git source fallback

Agentic Optimizations

ContextCommand
Status + pin audit/configure:surface --check-only
Scaffold + harden/configure:surface --fix --pin v0.8.0
The gate (CI)surf check
Scope to changed filessurf check --base origin/main
Machine-readable verdictsurf check --format json
Re-seal after human reviewsurf verify
Anchors resolvesurf lint

Flags

FlagDescription
--check-onlyReport adoption + pin hygiene without modifying files
--fixApply scaffolding and hardening without prompting
--pin <tag>Release tag to install/pin (resolved to a SHA before writing refs)

Upstream contributions

  • Installer pin — reported, merged, shipped: action.yml now runs the bundled ${{ github.action_path }}/install.sh, so a SHA-pinned uses: also pins the installer. Released; the caveat in Step 5 applies only to v0.6.2 and earlier.
  • Floating version: default — reported, open (Connorrmcd6/surface#169): proposes the default itself stop being latest, so the SHA pin becomes transitive. Independent of the fix here — set version: explicitly regardless, since anyone pinning an older release needs it.

See Also

  • /configure:web-session — install surf in Claude Code web sessions
  • /configure:pre-commit — pre-commit framework setup this plugs into
  • blueprint:blueprint-docs-currency — same-commit doc discipline (the convention-level complement)
  • blueprint:blueprint-sync — drift detection for generated content
  • code-quality:code-review — the semantic reviewer for Surface's JSON verdicts
  • Surface docs: https://surface.gradientdev.xyz/ · License: Apache-2.0
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

MIT

源路径

configure-plugin/skills/configure-surface

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3