Brief Copilot through COPILOT_CUSTOM_INSTRUCTIONS_DIRS instead of a prompt preamble - #360
Merged
Merged
Conversation
…reamble Copilot searches the directories that variable lists for *.instructions.md files, not for AGENTS.md. The July measurement that concluded the variable was ignored ran on 1.0.75 with a working cwd control, but only tried AGENTS.md and .github/copilot-instructions.md. Re-measured on 1.0.75 through 1.0.84-5, an instructions/*.instructions.md under a listed directory lands in the system message every time. The briefing directory now carries that copy, every Copilot launch (fresh, resumed, local, remote, daemon and app) appends the directory to the user's own value, and the opening prompt no longer carries the read-this-file pointer. --add-dir stays.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Copilot loops now receive the graph briefing as a system-level custom instruction through
COPILOT_CUSTOM_INSTRUCTIONS_DIRS, instead of a "Before anything else, read the briefing file at …" preamble on every opening prompt. The source recorded that variable as ignored. It is not: Copilot searches the listed directories for*.instructions.mdfiles, and the earlier measurement only triedAGENTS.mdand.github/copilot-instructions.md.Why the old finding was recorded, and why it was wrong
~/.copilot/session-state,copilotVersion: 1.0.75) show a working-directoryAGENTS.mdcontrol that loaded, and the same file in a directory named by the variable that did not.copilot help environmentonly says "custom instructions files", so the negative result looked like the variable being ignored.system.messagefor each session rather than trusting the model's answer (140 pinned runs, 0 tool calls, 0 misattributed sessions):AGENTS.mdin cwdAGENTS.md.github/copilot-instructions.mdcopilot-instructions.md,CLAUDE.mdinstructions/x.instructions.md(with or withoutapplyTo).github/instructions/x.instructions.md,x.instructions.mdAGENTS.md(both load)zsh -i -l -c 'exec env …'launch shapeCOPILOT_CUSTOM_INSTRUCTION_DIRS--resumerebuilds the system message from the resuming process's environment (measured on 1.0.84-5 and 1.0.84-8): without the variable a resumed session loses the instructions, with it they return. So resume paths carry it too.-isession on 1.0.84-5,/instructionslistsgraphcode.instructions.md [external]with its path.Changes
SessionBriefing.writealso writesinstructions/graphcode.instructions.mdbesideAGENTS.md(same text; theAGENTS.mdbeside it is not loaded by Copilot, so nothing doubles).env COPILOT_CUSTOM_INSTRUCTIONS_DIRS="${COPILOT_CUSTOM_INSTRUCTIONS_DIRS:+$COPILOT_CUSTOM_INSTRUCTIONS_DIRS,}<briefing dir>": appended after whatever the user's login shell already set, and$HOME/…on a remote host. Covers the daemon's fresh, shed and resume launches and the app's attach and resume, local and remote..instructions.mdcopy for Copilot sessions only.--add-dirfor the briefing directory stays.SessionBriefingdoc comment now records what is true and why the earlier finding was recorded.Not changed
main(below).Test plan
45cd9477(= pushed head), private DerivedData:make test'sxcodebuild -scheme graphcode testexit 0 — 1832 tests / 195 suites / 0 failures. The literalmake testtarget cannot run in a worktree (generatedepends onbuild-ghostty, which needs the submodules), so its recipe was run directly.make check: exit 0 (swiftlint 0 serious, swift-format clean).scripts/cli-smoke.shagainst it: exit 0.main, dumped from both trees across every command builder (launchArguments,ZmxSessionLauncher.arguments/resumeArgumentslocal and remote,remoteEnsureInvocation, the app'slaunchPrefix/agentCommand/resumeCommand/sessionEnvironment/remoteCommand, summary and title invocations) × goal/time/turn × three briefing settings: 186 shapes per backend, 0 differences for Claude Code, Codex, OpenCode and pi. Every Copilot difference is the insertedenvprefix, the removed pointer, or the delivery manifest's added file.briefingEnvironmentand delivering the copy to every backend makesxcodebuild testexit 65 (onlyCopilotIsGivenTheVariable,aRemoteCopilotLoopIsDeliveredTheCopyItSearchesFor,aResumedCopilotSurfaceIsBriefedAgain,codexRidesTheSameWayCopilotDoes) and the parity diff flag 102–114 shapes on each other backend; restored before the gate.CopilotInstructionsDeliveryTestsexpand the variable in a realzsh: unset →<dir>,/mine,/theirs→/mine,/theirs,<dir>.Checklist
git commit -s) per the DCOmake test)make check)