Skip to content

docs(claude-ops): record why lanes staleness probe stays a body instruction (#864)#877

Merged
kyle-sexton merged 1 commit into
mainfrom
feat/864-lanes-precompute
Jul 21, 2026
Merged

docs(claude-ops): record why lanes staleness probe stays a body instruction (#864)#877
kyle-sexton merged 1 commit into
mainfrom
feat/864-lanes-precompute

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What

Evaluate the lanes skill's deterministic, read-only git probes against the pinned precompute convention (plugins/playbooks/skills/skill-authoring/reference/precompute-context.md) and either convert each to ! dynamic-context injection or record why it fails the four conditions.

Per-probe verdict

Git probe Location Verdict
git rev-parse --show-toplevel (repo root) SKILL.md front matter Already converted! injection with || echo fallback; shell: bash declared.
git rev-parse --show-toplevel (lane-config resolution) SKILL.md front matter Already converted! injection with || echo fallback.
staleness probe: git fetch origin + git symbolic-ref + git log <lane-launch-commit>..<default> -- <plugin-path> context/refresh.md Recorded reason it fails all four conditions — stays a body instruction.

The two front-matter probes were !-injected at the skill's creation (#616) and gained shell: bash in 0.17.2 — already compliant, nothing to convert.

Why the staleness probe is not an injection candidate

It fails every convention condition:

  • Not deterministic/read-only + not cheap/boundedgit fetch is a network round-trip (latency-variable, can hang) that also updates remote-tracking refs.
  • Not needed up front every invocation — consulted only when weighing a restart, not on a plain status/stop/start.
  • Not judgment-independent — needs a computed <lane-launch-commit> argument (the running lane's launch point) plus the pathspec of whichever plugin the lane runs; a single-pass injection cannot supply either.

Recorded inline in context/refresh.md so a future reader does not re-litigate it.

Automated gate

skill-quality Check 18 (precompute opportunity) scans only SKILL.md fenced shell blocks and is silent when the skill already injects with ! — lanes does — so the gate was already satisfied; this PR adds no new ! blocks.

Changes

  • context/refresh.md — durable "Not an ! injection candidate" note next to the staleness probe.
  • claude-ops version 0.17.20.17.3 + matching CHANGELOG entry (changelog-parity gate).

Verification

  • check-skill.sh lanes — PASS (0 errors, 0 warnings; markdownlint clean, 163/500 lines)
  • check-changelog-parity.sh --check and --check-bump origin/main — PASS
  • validate-plugins.sh + claude plugin validate . — PASS
  • markdownlint on changed files — 0 errors

Closes #864

Related

…uction (#864)

Evaluate the lanes skill's git probes against the pinned precompute
convention (plugins/playbooks/skills/skill-authoring/reference/precompute-context.md).

Findings:
- SKILL.md front matter — the two `git rev-parse --show-toplevel` probes are
  already `!` dynamic-context injections (with `|| echo` fallback and a
  `shell: bash` declaration). Nothing to convert.
- context/refresh.md — the mid-session staleness probe (`git fetch` +
  `git symbolic-ref` + `git log <lane-launch-commit>..<default>`) fails all
  four convention conditions and correctly stays a body instruction:
  conditional (only when weighing a restart, not up front every invocation),
  needs a computed `<lane-launch-commit>` argument a single-pass injection
  cannot supply, and its `git fetch` is an unbounded network round-trip that
  mutates remote-tracking refs (not pure-read).

Record that reason inline in refresh.md so the decision is durable, and bump
claude-ops to 0.17.3 with a matching CHANGELOG entry (changelog-parity gate).

Closes #864

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton enabled auto-merge (squash) July 21, 2026 17:34
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 42s —— View job


PR Review

  • Gather context and understand the request
  • Read changed files
  • Review for correctness, security, and alignment with guidelines
  • Post final review

This is a clean, well-scoped docs + patch-bump PR. Here's what I checked:

plugins/claude-ops/skills/lanes/context/refresh.md — the core change

The added "Not an ! injection candidate" block is logically sound. I verified it against precompute-context.md, which lists four conditions that must all hold for ! injection. The note covers all four:

Convention condition Addressed in note
Deterministic and read-only ✅ "updates remote-tracking refs"
Needed up front, every time ✅ "conditional, consulted only when weighing a restart"
Independent of Claude's judgement ✅ "needs a computed argument (<lane-launch-commit>, plus the pathspec …)"
Cheap and bounded ✅ "neither bounded nor pure-read — a network round-trip"

One minor observation: the note bundles conditions 1 and 4 under a single "neither bounded nor pure-read" phrase while saying the probe "fails every condition." A reader counting reasons (three in the note) against conditions (four in the referenced doc) might need a moment. It's not wrong — both aspects of the git fetch violation are stated — but an explicit split ("not read-only" / "not cheap") would make the four-for-four claim immediately legible. That said, this is durable rationale for a technical audience already familiar with the precompute doc, so I'd leave it to the author's judgement whether to split.

No bugs, no security concerns here.

plugins/claude-ops/CHANGELOG.md

Correctly placed at the top as [0.17.3], ### Changed, Keep a Changelog format. The summary accurately reflects what changed and cites the issue (#864). No issues.

plugins/claude-ops/.claude-plugin/plugin.json

0.17.20.17.3 is the right semver tier for a documentation-only patch. No other fields changed. ✅

CLAUDE.md guideline alignment

  • No hardcoded paths or project-specific values in the new prose ✅
  • No PII or secrets ✅
  • Version bumped with changelog-parity ✅
  • Plugin-form-safe (no ../ references, no new file writes to plugin data paths) ✅

Overall: LGTM. The reasoning is accurate, the note is durable, and the mechanics (version + changelog) are correct. The one legibility nit above is optional; the PR is mergeable as-is.

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 2s —— View job


Security Review

  • Gather context and read changed files
  • Analyze diff for security issues
  • Post findings

No security issues found.

This PR is a documentation-only change with a version bump. The three changed files introduce no new executable code, no new configuration surfaces, and no new trust boundaries.

What was reviewed:

  • plugin.json — version field bumped 0.17.20.17.3; no other changes; no new userConfig keys, permissions, or external references.
  • CHANGELOG.md — prose changelog entry only.
  • context/refresh.md — 10 lines of explanatory prose added ("Not an ! injection candidate" block); no new commands, scripts, or interpolation surfaces introduced. The pre-existing illustrative bash snippet (git fetch / git log) was not modified by this PR and falls outside the diff scope.

No GitHub Actions workflows, hook scripts, MCP server definitions, secret-handling paths, or dependency pins were touched.

@kyle-sexton
kyle-sexton merged commit 86ed73b into main Jul 21, 2026
24 of 26 checks passed
@kyle-sexton
kyle-sexton deleted the feat/864-lanes-precompute branch July 21, 2026 17:36
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
An unrelated claude-ops docs PR (#877, closing #864) merged since this
branch's last rebase and landed at exactly 0.17.3 — the same version this
branch was claiming. Re-bumped claude-ops to 0.17.4 to clear the exact
collision (plugin.json auto-merged to an identical-looking "0.17.3" string
without flagging a conflict, since both sides happened to write the same
literal text for unrelated reasons; caught by diffing main's version history
directly, not by trusting a clean auto-merge). CHANGELOG.md split into two
sections (0.17.3 for #877's actual change, 0.17.4 for this PR's).

Also swept for new open PRs against all 5 plugins post-merge: #870
(feat/800-audit-instructions) newly touches repo-hygiene (claims 0.4.5) and
claude-ops (claims 0.17.2) — both below this branch's current claims
(0.4.6 / 0.17.4), no collision. source-control (0.15.11), work-items
(0.19.1), and guardrails (0.9.6) re-confirmed against current main and every
live open PR (#840 0.15.10, #844 0.17.2, #861 0.19.0) — unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
Resolves plugin.json/CHANGELOG.md conflicts: keeps this PR's 0.17.4
bump (past main's 0.17.3, landed via #877) and preserves the 0.17.3
changelog entry as-is.
kyle-sexton added a commit that referenced this pull request Jul 25, 2026
… as deliberate (#853)

## Summary

Closes the design fork raised in #820: whether the shell assert-helper
duplicated across
5 plugins (and the divergent per-script exit-code taxonomies alongside
it) should be
consolidated into a shared mechanism, or documented as deliberate. This
PR documents.

## Fix

- Adds `docs/conventions/shell-test-helpers/README.md` as the owner doc
explaining why the
duplication and divergence stay as-is, and registers it in
`docs/PLUGIN-PHILOSOPHY.md`'s
  convention registry table.
- Adds a one-line pointer comment at each copy site back to the owner
doc:
`guardrails/hooks/guardrails-test-helpers.sh`,
`claude-ops/hooks/claude-ops-test-helpers.sh`,
`source-control/scripts/test-helpers.sh`,
`repo-hygiene/skills/clean/scripts/lib/test-helpers.sh`,
  `work-items/tools/work-item-tracker/tests/lib.sh`.
- Adds the same kind of pointer to
`scripts/check-skill-portability.test.sh`, which opted out
for an unrelated reason (it's repo tooling, not a plugin, so no plugin
assertion library
applies) — noted so the fork's second observation isn't left
unexplained.
- Bumps `plugin.json` + adds a `CHANGELOG.md` entry for every plugin
whose helper file gained
the pointer comment. Each has been re-derived from current `main` many
times as sibling PRs
  merged or rebased mid-flight (see Related for the current picture):
  - `repo-hygiene`: 0.4.4→0.4.6
  - `source-control`: 0.15.7→0.16.1
  - `claude-ops`: 0.17.1→0.17.5
  - `work-items`: 0.18.1→0.20.1
  - `guardrails`: 0.9.5→0.9.6 (no open-PR collision at any point so far)

No behavior change anywhere — comments and docs only.

## Decision

**Chose Option B: document the per-plugin duplication and exit-code
divergence as deliberate.
No shared helper introduced.**

Investigation before deciding:

- This repo already has one sanctioned cross-plugin shared-source
mechanism: a canonical file
under `lib/` (e.g. `lib/hook-utils.sh`), copied — not imported — into
each carrying plugin by
a dedicated `scripts/sync-*.sh`, tracked in
`scripts/cross-plugin-source-registry.txt`, and
  drift-checked by `scripts/check-cross-plugin-source-drift.sh --check`.
- That mechanism is scoped to clusters meant to stay **byte-identical**.
Running
`check-cross-plugin-source-drift.sh discover` confirms it never even
flags the five
assert-helper files as a cluster candidate — they live at different
paths per plugin and
are not byte-identical, so they fall outside that mechanism's scope
entirely.
- Reading all five files: they are already three genuinely different
shapes, not one library
that drifted — a hook-contract shape (`guardrails`/`claude-ops`:
`ok`/`bad`, `PASS`/`FAIL`,
`make_sink`/`wait_for_sink`), a skill-script shape
(`source-control`/`repo-hygiene`: `pass`/`fail`,
`FAILED`/`CASE_NUM`, file-existence assertions), and a vendored-seam
shape (`work-items`: same
primitives, but owned by the seam itself so it stays correct wherever
the seam is resolved
  from, independent of this repo's tooling).
- Consolidating would mean designing a fourth, unified assertion API and
rewriting every
existing `*.test.sh` onto it — a bigger, riskier change than the
coupling it would remove,
and it would cross the plugin-independence boundary
`docs/PLUGIN-PHILOSOPHY.md`'s design
boundary section already draws (no plugin imports files from a sibling
plugin).
- Exit-code taxonomies (`remove-path.sh` 0/1/2/3/4,
`git-tree-reset-batch.sh` 0/1/2 forwarding
a child's 5/7, `check-skill-portability.sh` 0/1/2) encode genuinely
different per-script
contracts, not arbitrary numbering — each script already documents its
own `Exit:` line, and
a shared usage/exit helper would either flatten those contracts or grow
per-caller branching.
- Deferred, not rejected: `guardrails-test-helpers.sh` and
`claude-ops-test-helpers.sh` are the
one pair that already share a shape closely. If they converge to
byte-identical, vendoring
just that pair through the existing `lib/` + `sync-*.sh` + registry
mechanism is the smaller,
precedented move — recorded as the trigger in the owner doc rather than
acted on now.

## Verification

- `shellcheck` clean on all 6 edited shell files.
- Full `check-skill-portability.test.sh` suite: 16/16 pass.
- `check-cross-plugin-source-drift.sh --check`: no unregistered or
drifted clusters.
- `check-changelog-parity.sh --check`: passes with every version bump.
- Ran every `*.test.sh` that sources an edited helper
(repo-hygiene/clean, guardrails hooks,
claude-ops hooks, work-items adapters/lib) — all green, confirming the
comment-only edits
  changed no behavior.
- `markdownlint-cli2` and `lychee` clean on the new and modified docs.

## Related

- Scope note: issue #820's title says "disk-hygiene/clean", but
`disk-hygiene` is Python-only
(`hygiene.py`) with no shell assert-helper — the actual duplication
lives in the 5 plugins
the issue body names (repo-hygiene, source-control, guardrails,
claude-ops, work-items) plus
root `scripts/`. Treating the title as a triage typo (disk-hygiene vs.
repo-hygiene, both
"-hygiene" plugins with a `clean` skill) rather than touching
disk-hygiene.
- **`do-not-merge` held.** This session has had exceptionally heavy
concurrent-lane traffic
against these same 5 plugins — this PR has been rebased/re-derived nine
times as siblings
merged (#839, #826, #857, #877, #870, #844) or rebased in place (#840,
#882, #861, each more
than once). Current picture, last verified fresh at commit `e75e45ed`
(`mergeable: MERGEABLE`;
all 5 plugins re-checked against current `main` AND every live open PR):
- `repo-hygiene` (claims 0.4.6): no open-PR collision. Main is at 0.4.5.
- `source-control` (claims 0.16.1): held behind **#882**
(`fix/511-babysit-self-identity-decouple`,
claims 0.16.0, open) and **#840** (claims 0.15.10, open). Main is at
0.15.9.
- `claude-ops` (claims 0.17.5): **no open-PR collision anymore** — #844
(the PR this leg was
previously held behind) has merged, landing at exactly 0.17.4; this
claim stays one past it.
    Main is at 0.17.4.
- `work-items` (claims 0.20.1): held behind **#861**
(`feat/613-mini-sdlc-pipeline-ssot`). #861
itself has re-derived its claim twice as `main` moved — from 0.19.0 up
to 0.20.0 (following
#857's Jira-adapter minor bump into main) — so this PR's claim moved
from 0.19.1 to 0.20.1 to
    stay ahead. Main is at 0.19.0.
  - `guardrails` (claims 0.9.6): no open-PR collision. Main is at 0.9.5.
- This plugin set has produced a new collision within minutes of nearly
every prior check —
including siblings re-deriving their own claims upward more than once,
an unrelated PR
landing at the exact same version by coincidence, and legs clearing and
new ones opening.
Re-run the full collision protocol (`gh pr list --repo
melodic-software/claude-code-plugins
--state open --json number,headRefName,files` filtered per plugin, AND a
fresh diff of each
plugin's version on `main` since this PR's last rebase) immediately
before removing
    `do-not-merge` — do not trust this snapshot.

Closes #820

Work-class: C2 (mechanical) — attended triage 2026-07-23,
operator-ratified. 🤖

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

claude-ops: lanes git probes are precompute candidates (!-injection)

1 participant