Skip to content

feat(app-control): add /app-control:map refresh - #9934

Merged
kyle-sexton merged 50 commits into
mainfrom
feat/9583-map-refresh
Oct 25, 2026
Merged

kyle-sexton merged 50 commits into
mainfrom
feat/9583-map-refresh

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Closes #9583

Summary

Adds the refresh action to /app-control:map, so the map's only writer also keeps a control skill current. It ports testing:refresh-feature-map steps 1-6 and their outcomes (clean, changed, blocked), and adds a source wave capped at 6, one live pass through /app-control:drive, and triage of each problem as doc drift, driver gap or product regression.

Fix

  • map refresh edits only the control skill's directory and commits on control-skill-upkeep/<slug>. An existing feature-map-upkeep/<slug> branch is reported, never adopted.
  • A product regression is reported and kept out of the upkeep PR. A legacy flat features/<f>.md map is migrated to a folder in the same upkeep PR.
  • upkeep-skip.sh and its test are copied into map/scripts/. No script-fingerprint verbs.
  • Eleven refresh cases and feature-map-maintainer-confines-edits are ported. Five cases are new: one per triage class, legacy-flat-map-migrates and source-wave-capped-at-six. One app-control changelog fragment (minor).

Verification

  • bash plugins/app-control/skills/map/scripts/upkeep-skip.test.sh exits 0. check-map.test.sh prints "37 cases, 0 failed". scripts/check-line-citations.py exits 0. /skill-quality:check map PASS (0 errors). /evals:validate exits 0.
  • grep -n 'control-skill-upkeep/' plugins/app-control/skills/map/SKILL.md matches line 185. grep -n -i fingerprint on the same file prints nothing.
  • claude plugin eval, Claude Code 2.1.310, 3 runs per arm, judge opus, no Bash, all VALID. New cases with the plugin vs without: doc drift 1.00/0.17, driver gap 1.00/0.00, product regression 1.00/0.00, legacy-flat-map-migrates 1.00/0.25, source-wave-capped-at-six 1.00/0.50. Ported feature-map-maintainer-confines-edits, run concurrently: before (testing@db62cbf3f) 1.00, after 1.00.
  • The eleven ported refresh cases (skill-creator evals.json, which claude plugin eval does not run) were run concurrently before and after with blind graders: suite mean 97.73 on both sides, no case lost or dropped. The evidence is in a PR comment.
  • Left out: Bash-granting eval runs (this host's eval sandbox refuses them), trigger-rate measurement.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 26 commits October 24, 2026 02:37
…I and safety sections

Map create discovers the repository over fixed rows before asking
anything, asks only the residue (through /planning:interview when
installed), writes the control skill and proves it once through
/app-control:drive. The contract gains config layering, driver CLI and
safety-floor sections. The 16 map-features cases and the unsafe-location
case are ported, and six new cases cover discovery order, recipients,
sign-in lockout, unattended stops, evidence survival and config layers.

Refs: #9581

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…harpen the map eval cases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…its graders

Discovery stays read-only; the check that the app runs goes through
/app-control:drive and its cleanup, and the no-orphan check covers every
launch record drive wrote. The writer case can now fail its Write grader,
the config and recipient regex graders match only what a correct answer
says, case 12 keeps its refresh-skill expectation, and the run-/verify
location rule states our reason in our words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
… pin the control-skill location

- --dir accepts only another .claude/skills/control-<slug> directory, the one place drive looks;
  real paths of the target, ignore file and pointer target must stay inside the repository.
- The generated driver CLI applies the safety floors from config committed at HEAD and refuses a
  loosening from the local, environment or flag layers with exit 4; send, sign-in and write steps
  are CLI commands. Credentials always come from environment variables.
- One sign-in rule first: any failure counts, one attempt per account per create run across every
  drive call, one capped rerun. No state file.
- Explicit drive call sequence with the app slug and one --out per drive run outside the checkout;
  the no-orphan check matches pid, start time and command-line hash.
- Hub last in the write order, resumable partial create, config/.gitignore checked with
  git check-ignore, unattended create is a dry run.
- Hub table gains the app, driving tool and Attended runs only. rows.
- Evals: id 12's always-true expectation replaced, the ported location case no longer forbids
  writing in its prompt, and the recipient and config cases grade the CLI as the enforcer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…ecipient case's phrasing check

The plugin description now names /app-control:map beside drive, with the catalog row
regenerated. The recipient case's regex also accepts a negation pointing back at the
allowlist ("isn't on it"), and its judge accepts an allowlist that stays empty until
committed at HEAD; both edits were made after a first run (regex failed 3 of 3 on
phrasing while the reply refused the unlisted recipient through the CLI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…haracter limit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…efaults are committed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
… map create

Name the caller as the keeper of the per-run sign-in count, pass
--unattended through to drive, launch nothing while a side-effect or
shared-system row is open, recommend only safe values for safety
questions, report discovered secrets by file and key, real-path check
every written file, test the CLI's floor refusals in the proof, align
the README and eval graders with the contract, and fix the upstream
record's line citations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
Carry the untrusted-content framing spine verbatim, give the driver CLI
a side-effect-free config command and test the floors through it with
an exit-4-only pass, let the Floors check decide a resumed CLI, derive
the drive selector from the resolved --dir slug, and skip the start
check when drive would pick another app's sole control skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
check-map.sh reports a control skill's structural contract breaks as
`<rule> | <path> | <detail>` lines (index to folders, sections, entry-point
markers, links, shared/ use and why line, source globs), never edits, and
exits 0 with findings. The map body's check action runs it, then judges
copied recipes. Three eval cases cover a dead index line, a missing
not-driven reason and a copied recipe, each with no file change.

Refs: #9582

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
…contract

check-map.sh's shared-use and shared-why rules now point at the
contract's "Shared items" section instead of being the only home for
the convention.

Refs: #9582

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177ybXguBnnGV4UTksrdzd9
Refresh keeps a control skill in line with the app: skip check, a
read-only source wave in waves of at most six, a live pass through
/app-control:drive under the Ready/cleanup/evidence invariants, and
triage into doc drift, driver gap and product regression. Changes go out
on control-skill-upkeep/<skill slug> through one pull request; legacy
testing feature maps and flat feature files convert in the same pull
request. Ports upkeep-skip.sh and its test, the 11 refresh cases and the
confines-edits case, and adds five new cases.

Refs: #9583

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ding .claude

Inside an enclosing git repository, the git top level is not the
project, so every index source glob looked dead. The default root is now
the directory holding .claude/ (the git top level only for a directory
outside .claude/skills/), the contract says sources are relative to it,
and the no-shell fallback reports only what the rules find. The check
evals now require the action's `<rule> | <path> | <detail>` line, which a
run without the skill does not produce.

Refs: #9582

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
map-legacy-flat-map-migrates seeded files into a repository with no
commit, so the refresh correctly stopped as blocked at the skip check.
The scaffold now initializes a repository when none exists and commits
the seeded tree on main with a fixed author and date.

Refs: #9583

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tory

map uses <slug> for the app slug, so `control-skill-upkeep/<skill slug>`
read as control-skill-upkeep/clockwork. Name it
control-skill-upkeep/control-<slug> everywhere, with the never-form
beside the example, and move the cursor-pstack citation of the
conversion section to its new lines.

Refs: #9583

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…epository

`git rev-parse --git-dir || git init` committed into an enclosing
repository when the scaffold ran inside one. Init here unless this
directory is already a repository's top level.

Refs: #9583

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep refresh in map's argument-hint with unspaced alternatives, and mark
the literal backticks in the source-wave scaffold for shellcheck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main now holds map create (#9628) and map check (#9921) squashed. Their
files take main's version; refresh composes onto main's SKILL.md,
evals.json, README and the cursor-pstack record. The released map-create
fragment and a sample for a grader main renamed are removed, and the
cheat sheet is regenerated.

Refs: #9583

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton

Copy link
Copy Markdown
Member Author

Ported-case non-inferiority (skill-creator evals.json format, run the way Phase 4 ran it in #9628): testing:refresh-feature-map at db62cbf vs /app-control:map refresh at e8f3581, all 22 executors run concurrently, with-skill arm, each side graded on its own suite by blind fresh-context graders, no shell.

Before After Before % After %
1 no-map-blocks 17 refresh-no-control-skill-blocks 100 100
2 skip-when-unchanged 18 refresh-skip-when-unchanged 100 100
3 unattended-chrome-refused 19 refresh-unattended-attended-only-refused 100 100
4 renamed-handle-corrected-in-map-only 20 refresh-renamed-handle-corrected-in-skill-only 75 75
5 lost-behavior-reported-not-mapped 21 refresh-lost-behavior-reported-not-mapped 100 100
6 open-pr-updated-not-duplicated 22 refresh-open-pr-updated-not-duplicated 100 100
7 clean-pass-records 23 refresh-clean-pass-records 100 100
8 driver-unavailable-writes-no-candidate 24 refresh-driver-unavailable-writes-no-candidate 100 100
9 working-tree-changed-during-source-pass 25 refresh-working-tree-changed-during-source-wave 100 100
10 untracked-map-committed-with-corrections 26 refresh-untracked-skill-committed-with-corrections 100 100
11 untracked-map-with-outside-change-blocked 27 refresh-untracked-skill-with-outside-change-blocked 100 100

Suite mean 97.73 before and after; no case lost, none dropped. Non-inferior under skill-criteria step 6.

  • Case 4/20 misses on both sides on the same expectation (edits the handle in the feature file): both runs held the edit behind the attended ask that expectation 3 requires. Graders flagged that the two expectations conflict on an attended pass. The expectations were left unchanged.
  • Cases 6/22, 7/23 and 10/26 were graded on the recorded commit, push or record decision on both sides, since the executors had no shell.
  • 20 of 22 runs score at the ceiling, so this suite separates the two sides very little.

kyle-sexton and others added 6 commits October 25, 2026 04:29
A reply that read only SKILL.md planned to edit cli/ and re-drive on an
unattended pass, because the rule lived only in refresh.md's triage table.
The hub now says an unattended pass reports the fix unwritten and drives
nothing again. A flat feature file's conversion also updates its hub
index line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"The send failure is a driver gap" matched no branch of the names-*
graders. A branch for the class right after "is" or "as" covers it, while
"is not a" still fails; pass and fail samples cover both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… blocked

An unattended pass now reports a driver-gap fix unwritten. Ending it clean
would record the pass and let the next one skip the unfixed gap, so it ends
blocked and records nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…asses

class(?:es|ed) matches what classe[sd] matched; labelled becomes labeled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton

Copy link
Copy Markdown
Member Author

Local code and security reviews ran at ready, because review-venue read both CI lanes as absent. What happened to each finding:

Finding Disposition Basis
Sec 1: a fork PR with the upkeep branch name is taken as the upkeep PR VALID (defer), #9937 Also on main: plugins/testing/skills/refresh-feature-map/SKILL.md:177
Sec 2: the source wave is read-only by prompt only, with no framing VALID (defer), #9938 Also on main: refresh-feature-map/SKILL.md:96-98
Sec 3: an unattended driver-gap fix edits cli/ (which enforces the floors) and re-drives VALID (fix now) An unattended pass reports the fix unwritten and ends blocked; case map-triage-driver-gap-unattended added
Sec 4: a refreshed control skill skips create's real-path checks VALID (fix now) Given and globbed directories are held to naming.md#real-paths, re-run before each write
Sec 5: --unattended now commits, pushes and opens a PR No change refresh-feature-map on main already runs unattended scheduled passes that open a PR; the approved plan ports it
Code C1: upkeep-skip.sh is copied in two plugins No change in this PR The copy is required (A4). Phase 8 (#9585) deletes the testing copy, so a sync check would be removed almost at once
Code I1: branch control-skill-upkeep/control-<slug> vs <slug> INCORRECT #9583 says <slug>; the branch is named for the control skill, one per skill, and the sanity grep matches
Code I2: feature-map-upkeep/<slug> cannot be derived VALID (fix now) Every feature-map-upkeep/* branch is listed and reported by name; case map-reports-legacy-upkeep-branch added
Code I3: the wave grader requires 6+2 but the skill allows any split VALID (fix now) The skill now fills each wave to the cap; the grader is unchanged
Code I4: the description overlaps testing:refresh-feature-map VALID (fix now) The phrase is dropped; a legacy map converts only when its path is passed
Code I5: flat control-skill conversion and multi-skill passes are untested VALID (fix now) Cases map-converts-flat-control-skill and map-refreshes-each-control-skill added
Code S1: a multi-skill pass stays on the first upkeep branch VALID (fix now) The pass returns to its starting branch after each skill
Code S2-S5: ## Next shape, triage regexes, branch-grader boundary, fixture hub rows VALID (fix now) Fixed, with fail samples for the regexes

Evals at 726e4b6 (claude plugin eval, 3 runs per arm, no Bash, all VALID), scored with the plugin and without:

Case With plugin Without
map-triage-driver-gap 1.00 0.00
map-triage-driver-gap-unattended 1.00 0.00
map-triage-doc-drift 1.00 0.00
map-triage-product-regression 1.00 0.00
map-source-wave-capped-at-six 1.00 0.50
map-legacy-flat-map-migrates 0.92 0.25
map-reports-legacy-upkeep-branch 1.00 0.50
map-converts-flat-control-skill 1.00 0.33
map-refreshes-each-control-skill 1.00 0.00

The last commit, ce769c8, changes only the outcome rule for an unwritten driver gap; no case grades that outcome word.

@kyle-sexton
kyle-sexton marked this pull request as ready for review October 25, 2026 08:48
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T08:50:18.837806Z edf85d7 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-security-review: 1 inline finding(s) on edf85d76c8493c445a98621a7ae3e6b8b1825eaa; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread plugins/app-control/skills/map/reference/refresh.md
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 40451ac8f2ebdc2be2d776fb637bf5e39fd5967a: 0 finding(s), 0 as inline comments.

I found no issues in the incremental change, which covers the 8 files that changed since 3410a23. I read .claude-lane/incremental.diff, the PR context, and the current refresh.md. Nothing here runs: it is skill prose, an eval case and a fixture, so I did not run the eval or the scaffold script.

  • Dirty-map block and copy-based undo (plugins/app-control/skills/map/reference/refresh.md:87-107). The new text is internally consistent.
    • The git status --porcelain -- "<legacy dir>" check runs before the planned-conversion ask, the upkeep-branch step 6.1 and any write. Only ?? lines are tolerated, so untracked notes in the map do not block it. Staged or unstaged edits to tracked files do.
    • The copy to mktemp -d is taken after the branch step and before the first git mv, so it holds the pristine legacy directory.
    • The undo steps cover the index and the working tree. The legacy files are put back from the copy, and the copy is deleted only after a clean undo or after step 6.3 commits.
  • Changelog fragment (.changes/app-control/feat-9583-map-refresh-29fdd303.md). It matches the new behavior: a dirty tracked map blocks, and the undo restores from a copy taken outside the checkout. The bump level is still minor.
  • Line citations (docs/upstream/cursor-pstack.md). I checked the ranges against the head file, and they now land on the right sections:
    • 85-127 is the source wave.
    • 129-150 is the live pass.
    • 152-161 is the triage.
    • 214-240 is Converting a legacy map.
  • New eval map-legacy-dirty-map-blocks.
    • The scaffold commits a clean legacy map and then appends one uncommitted line to a tracked file, which matches the case's ls-style expectation of M .claude/skills/feature-map/start-a-timer.md.
    • The slug control-clockwork-web follows from the fixture's Application line.
    • The regex grader's \bblocked\b does not match "unblocked", as the fail sample shows. Together with the LLM grader, it can tell a refusal from a converted map.
    • The prompt tells the model that git status prints the dirty line and that the decide step prints run, so the case does not depend on a shell.

No hold. The change spends no billed resources.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 40451ac8f2ebdc2be2d776fb637bf5e39fd5967a: 0 finding(s), 0 as inline comments.

No security findings in the incremental change since 3410a23.

What changed

  • plugins/app-control/skills/map/reference/refresh.md is an instruction-surface edit. It adds two behaviours:
    • A legacy map with uncommitted changes to tracked files now ends blocked before anything is written.
    • The undo path now restores the legacy files from a copy taken outside the checkout, instead of from git restore --source=HEAD.
  • The changelog fragment and the docs/upstream/cursor-pstack.md row are prose and line-citation updates.
  • The new eval map-legacy-dirty-map-blocks has a fixture, a sample file and scaffold.sh.

Instruction-exception check

  • I did not read docs/conventions/instruction-exception-register/README.md, so the protected-class list was not consulted. I fell back to judging by consequence.
  • The diff removes no control. It narrows the old git restore --source=HEAD undo, which would overwrite uncommitted edits. The new dirty-map guard blocks before any write, so nothing can be overwritten.
  • The undo now deletes only paths the conversion listed, plus any directory the conversion created that is left empty. Those paths sit under .claude/skills/control-<slug>/, and the real-path checks still run before each write. I found no way in the diff to point the deletion at an unrelated path.
  • The backup is made with mktemp -d outside the checkout. It holds only the legacy map's own files. The report names its path, and it is deleted only after the undo finishes or step 6.3 commits.

Other files

  • scaffold.sh runs in an eval sandbox. It guards git init so it never commits into an enclosing repository, and it only touches files under its own directory.
  • The fixtures, case.yaml and the sample JSON are inert data.
  • No .github/standards/trusted-actors/**, check-trusted-trigger, CODEOWNERS or .gitmodules file changed, and no plugin manifest changed, so there are no manifest <field> lines.

critical-findings: 0

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edf85d76c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/app-control/skills/map/reference/refresh.md
Comment thread plugins/app-control/skills/map/reference/refresh.md
kyle-sexton and others added 4 commits October 25, 2026 04:58
Drive reads only control skills, so a legacy conversion's live pass had
nothing to drive. The conversion is now written first, uncommitted on the
upkeep branch, and both passes read the converted control skill. A pass
that stops before the commit leaves those files in the working tree and
names them. The legacy migration eval asks for the step order and judges
it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…li/ steps

The Config bullet called any write with no cli/ a driver gap, wider than
the contract's "writes to an environment or external system", so a
refresh read a click on the app's own scratch data as a gap and ended
blocked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… specifies

Plugin evals load no source-control plugin, and refresh step 6.4 then leaves
the commit on the upkeep branch and reports the pull request as still to open.
The grader and expected outcome now ask for that; a separate branch or pull
request still fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An entry already marked not driven is recorded state. Only a cli/ command the
live pass found failing or missing, and left unwritten, ends the pass blocked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-security-review: 1 inline finding(s) on 5e61ebd204c10f6bd818fef248cb40de9b78965d; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread plugins/app-control/skills/map/reference/refresh.md Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 5e61ebd204c10f6bd818fef248cb40de9b78965d; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment thread plugins/app-control/skills/map/reference/refresh.md Outdated
kyle-sexton and others added 2 commits October 25, 2026 05:49
…e pass stops

An attended pass now shows the planned conversion and asks before the first
write. A pass that stops before its commit moves the files back and returns to
its starting branch, so the checkout is clean for the next run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lat case

The stricter wording failed a reply that stated step 6.4's plugin-absent
branch as a condition. Either route on the one upkeep branch passes; a
separate branch or pull request still fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-security-review: 1 inline finding(s) on 3410a23ab2d4fcf4c16c8d9785c9563b477324cb; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread plugins/app-control/skills/map/reference/refresh.md Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 3410a23ab2d4fcf4c16c8d9785c9563b477324cb; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment thread plugins/app-control/skills/map/reference/refresh.md Outdated
…y map

A refresh now refuses to convert a tracked legacy map with uncommitted
changes, copies the legacy directory outside the checkout before the
conversion's first write, and lists every path the conversion creates.
The undo unstages and deletes those paths and copies the legacy files
back from the copy instead of restoring from HEAD, so it works for an
untracked map and leaves the tree as it was before the pass. A new eval
case covers the dirty-map refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit 7321998 Oct 25, 2026
35 checks passed
@kyle-sexton
kyle-sexton deleted the feat/9583-map-refresh branch October 25, 2026 14:26
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.

feat(app-control): add /app-control:map refresh

1 participant