MUL-5261: revert domain-specific prompt additions (#5913)

Revert the built-in focused-testing skill (#5877) and the always-on
Repository Setup Preflight brief section (#5886). Both delivered
software-engineering domain content through platform-level prompt
surfaces that every agent receives regardless of workspace type.

- multica-focused-testing was the only built-in skill that did not
  describe a Multica platform contract, and the only one without
  `user-invocable: false` / `allowed-tools: Bash(multica *)`. Built-in
  skills are meta/system skills; a workspace with no repository bound
  still carried it in its skill index and slash-command menu.
- Repository Setup Preflight was emitted for every non-quick-create task
  without consulting `ctx.Repos`, so non-code workspaces received
  build/dependency instructions in the always-on brief. writeRepositories
  already elides itself when no repo is bound; this section did not.

Pure revert. No replacement behavior is introduced here.

Co-authored-by: Lambda <lambda@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Jiayuan Zhang
2026-07-25 02:47:06 +08:00
committed by GitHub
parent ecce589867
commit 28a4203bc2
11 changed files with 2 additions and 499 deletions

View File

@@ -111,10 +111,6 @@ func TestBuildMetaSkillContentSlimKindMatrix(t *testing.T) {
kindCommentTriggered: true, kindAssignmentTriggered: true,
kindAutopilotRunOnly: true, kindChat: true,
}},
{"## Repository Setup Preflight", map[taskKind]bool{
kindCommentTriggered: true, kindAssignmentTriggered: true,
kindAutopilotRunOnly: true, kindChat: true,
}},
{"## Issue Metadata", issueKinds},
{"## Instruction Precedence", map[taskKind]bool{kindAssignmentTriggered: true}},
{"## Sub-issue Creation", issueKinds},
@@ -156,51 +152,6 @@ func TestBuildMetaSkillContentSlimKindMatrix(t *testing.T) {
}
}
func TestRepositorySetupPreflightIsStackAgnostic(t *testing.T) {
t.Parallel()
var b strings.Builder
writeRepositorySetupPreflight(&b)
out := b.String()
for _, want := range []string{
"after `multica repo checkout`",
"Before editing code or running build/test commands",
"`AGENTS.md`, `README`, development docs",
"dependency manifests and lockfiles",
"missing, stale, or readiness is uncertain",
"documented, reproducible setup command",
"Do not reinstall when the existing environment is demonstrably ready",
"did not unexpectedly modify dependency manifests or lockfiles",
"Do not use a failing build or test run",
} {
if !strings.Contains(out, want) {
t.Errorf("repository setup preflight missing %q\n---\n%s", want, out)
}
}
for _, packageManager := range []string{"pnpm", "npm install", "yarn", "bun install", "pip install", "poetry", "cargo"} {
if strings.Contains(strings.ToLower(out), packageManager) {
t.Errorf("repository setup preflight must stay stack-agnostic; found %q\n---\n%s", packageManager, out)
}
}
brief := buildMetaSkillContent("codex", TaskContextForEnv{
IssueID: "issue-1",
Repos: []RepoContextForEnv{{URL: "https://example.com/repo.git"}},
})
repositoriesIndex := strings.Index(brief, "\n## Repositories\n")
preflightIndex := strings.Index(brief, "\n## Repository Setup Preflight\n")
if repositoriesIndex == -1 || preflightIndex <= repositoriesIndex {
t.Errorf("repository setup preflight must follow repository checkout guidance\n---\n%s", brief)
}
localBrief := buildMetaSkillContent("codex", TaskContextForEnv{IssueID: "issue-1"})
if !strings.Contains(localBrief, "\n## Repository Setup Preflight\n") {
t.Errorf("repository setup preflight must also cover an existing local working directory\n---\n%s", localBrief)
}
}
// TestSlimQuickCreateAvailableCommands locks the minimal-variant content
// for quick-create's Available Commands: `issue create` present, every
// other Core command absent (the hard guardrails forbid the call).

View File

@@ -30,8 +30,8 @@ import (
// 2. Per-section prose compression — Available Commands, Issue
// Metadata, Mentions, Sub-issue Creation, Comment Formatting,
// Always Use CLI, Background Task Safety, Task Initiator,
// Repositories, Repository Setup Preflight, Output are all
// tightened. Every test-asserted phrase stays.
// Repositories, Output are all tightened. Every test-asserted phrase
// stays.
//
// Background Task Safety is emitted by `writeBackgroundTaskSafetySlim`
// below.
@@ -299,20 +299,6 @@ func writeRepositories(b *strings.Builder, ctx TaskContextForEnv) {
b.WriteString("\n")
}
// writeRepositorySetupPreflight emits a stack-agnostic readiness check for
// every task surface that can perform repository work. It deliberately asks
// the agent to infer the repository's own setup contract instead of naming a
// package manager or forcing a reinstall on a warm workdir.
func writeRepositorySetupPreflight(b *strings.Builder) {
b.WriteString("## Repository Setup Preflight\n\n")
b.WriteString("Before editing code or running build/test commands in a repository (after `multica repo checkout`, or immediately when working in an existing local directory):\n\n")
b.WriteString("- Read the repository instructions and setup documentation (`AGENTS.md`, `README`, development docs), plus the relevant dependency manifests and lockfiles.\n")
b.WriteString("- Identify the stack and package/dependency manager, then determine whether the required dependencies and tools are already usable.\n")
b.WriteString("- If dependencies are missing, stale, or readiness is uncertain, run the repository's documented, reproducible setup command before proceeding. Do not reinstall when the existing environment is demonstrably ready.\n")
b.WriteString("- Check that setup did not unexpectedly modify dependency manifests or lockfiles; investigate unexpected changes before continuing.\n")
b.WriteString("- Do not use a failing build or test run as the way to discover that dependencies were not prepared.\n\n")
}
// writeProjectContext emits the Project Context section when the task carries
// an active project. Project context is independent of the task surface: an
// issue inherits it from its project, while a chat receives it from the
@@ -654,7 +640,6 @@ func writeOutput(b *strings.Builder, kind taskKind, ctx TaskContextForEnv) {
// Comment Formatting | ✓ | ✓ | — | — | —
// Repositories | △ | △ | △ | — | △
// Project Context | △ | △ | △ | △ | △
// Repository Preflight | ✓ | ✓ | ✓ | — | ✓
// Issue Metadata | ✓ | ✓ | — | — | —
// Instruction Precedence| — | ✓ | — | — | —
// Sub-issue Creation | ✓ | ✓ | — | — | —
@@ -696,10 +681,6 @@ func buildMetaSkillContentSlim(provider string, ctx TaskContextForEnv) string {
writeProjectContext(&b, ctx)
if kind != kindQuickCreate {
writeRepositorySetupPreflight(&b)
}
if kind.hasIssueContext() {
writeIssueMetadata(&b)
}

View File

@@ -1,41 +0,0 @@
---
name: multica-focused-testing
description: "Use when selecting or running a focused or targeted test in any user repository. Detect the repository's stack and runner first, prefer its commands, and verify discovery before execution. Not for an explicitly requested full-suite run."
---
# Focused testing
Run the narrowest runner-native scope without expanding it to a full suite.
## Workflow
1. Read repository instructions and test configuration. Verify the target,
ownership, build tool, and runner.
2. Prefer repository Agent configuration, then a dedicated repository script,
then a runner-native focused selector confirmed by configuration or local
`--help`. Infer only as a last resort.
3. Keep the target as a distinct argument. Do not guess whether a wrapper
forwards separators or positional arguments, and do not add a separator
unless the detected tool requires it.
4. Use list, collect, discovery, or dry-run mode first when available. Compare
it with the runner-native scope: file, package plus case, target, class,
module, or project. Never impose
`expected_file_count=1` on a runner that does not discover by file.
5. Run only when scope is confirmed. If discovery is broader or the target,
ownership, runner, or forwarding contract remains unclear, stop and correct
or report the gap rather than guessing.
## Stack reference
After detection, read exactly the matching reference:
- JavaScript or TypeScript: `references/javascript-typescript.md`
- Go: `references/go.md`
- Python: `references/python.md`
- Rust: `references/rust.md`
- JVM (Gradle or Maven): `references/jvm.md`
- .NET: `references/dotnet.md`
- Ruby: `references/ruby.md`
If no reference matches, use the repository's own instructions and the detected
runner's local help. Do not borrow a template from another stack.

View File

@@ -1,39 +0,0 @@
# .NET
Identify the owning project or solution and inspect repository build scripts
before calling `dotnet test`. Prefer a project file over a whole solution for a
focused run. Check the SDK and `global.json` first: .NET 10 can select either
VSTest or Microsoft.Testing.Platform (MTP), and their CLI contracts differ.
For VSTest, after confirming the adapter's filter support:
```text
["dotnet", "test", "path/to/project.csproj", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]
```
Verify the same filter without executing tests:
```text
["dotnet", "test", "path/to/project.csproj", "--list-tests", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]
```
`FullyQualifiedName` is available in the popular VSTest adapters, but the exact
value format and other filter properties vary. Confirm the discovered name from
`--list-tests`.
Do not reuse that argv for MTP. With the .NET 10 MTP driver, project selection
uses `--project`, while test-related arguments come from the registered
framework extensions and should be placed after a literal `--` when forwarding
would otherwise be ambiguous. Inspect `global.json`, the test framework, and
the local `dotnet test --help` / test-application help before constructing the
filter. Do not assume MSTest, NUnit, xUnit, or custom MTP extensions share a
universal selector.
## Official documentation
- Runner selection in `dotnet test`:
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test
- VSTest `--filter`, `--list-tests`, and filter properties:
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-vstest
- .NET 10 MTP project selection and argument forwarding:
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-mtp

View File

@@ -1,32 +0,0 @@
# Go
Go tests are compiled and selected by package and test name, not reliably by
running one `_test.go` file in isolation. Identify the owning module and package
from `go.mod` and the target path.
Use the package plus an anchored `-run` expression:
```text
["go", "test", "./path/to/package", "-run", "^TestName$", "-count=1"]
```
For a top-level test, verify discovery without running it:
```text
["go", "test", "./path/to/package", "-list", "^TestName$"]
```
`-list` does not enumerate subtests. For a subtest, use an anchored
parent/subtest expression, such as `^TestName$/^SubtestName$`, after confirming
the exact names from source or verbose output. Go splits `-run` expressions at
unbracketed `/` characters and may run a matching parent to discover its
subtests.
Do not pass a single `_test.go` file merely to imitate file-oriented runners:
that can omit package files, shared test helpers, or build-tag behavior. The
expected scope is the owning package with the requested test selected.
## Official documentation
- Go testing flags (`-run`, `-list`, and `-count`):
https://pkg.go.dev/cmd/go#hdr-Testing_flags

View File

@@ -1,46 +0,0 @@
# JavaScript and TypeScript
Inspect the nearest `package.json`, the workspace manifest, the lockfile, and
the runner config. Use the owning package's package-relative test path when a
workspace command changes the runner's working directory.
For pnpm plus Vitest, when repository configuration does not provide a
dedicated command, use this direct runner shape from the repository root:
```text
["pnpm", "--filter", "<workspace>", "exec", "vitest", "run", "<package-relative-test-file>"]
```
`pnpm exec` runs the dependency command in the selected project's scope and
passes options after `exec` to that command. Vitest treats a positional value
as a substring filter over test-file paths, so pass the full package-relative
path and verify that it uniquely identifies the requested file.
Do not use this shape for a focused run:
```text
["pnpm", "--filter", "<workspace>", "test", "--", "<test-file>"]
```
pnpm passes arguments after the script name to the executed script. In this
shape Vitest receives the literal separator before the path; that is not the
direct file-filter argv above and can expand discovery to the whole package.
For other package managers or runners, inspect the repository script and local
runner help. Do not translate the pnpm/Vitest argv mechanically.
If the installed Vitest version exposes `list` and `--filesOnly`, verify the
same filter before execution:
```text
["pnpm", "--filter", "<workspace>", "exec", "vitest", "list", "<package-relative-test-file>", "--filesOnly"]
```
Require exactly one discovered test file.
## Official documentation
- pnpm filtering: https://pnpm.io/filtering
- pnpm exec and option forwarding: https://pnpm.io/cli/exec
- pnpm run argument forwarding: https://pnpm.io/cli/run
- Vitest CLI file filters, `run`, and `list`: https://vitest.dev/guide/cli

View File

@@ -1,39 +0,0 @@
# JVM
Use the repository wrapper (`gradlew` or `mvnw`) and identify the owning module
before selecting a test. Build configuration may add plugins, profiles, or
environment required by the suite.
For Gradle, after confirming the task path:
```text
["./gradlew", ":module:test", "--tests", "package.ClassName.methodName"]
```
Use `gradlew.bat` on Windows. If the repository's wrapper exposes
`--test-dry-run`, add it first to inspect the selected tests without executing
them. Filters configured in the build script still apply alongside `--tests`.
For Maven Surefire, after confirming the module and plugin:
```text
["./mvnw", "-pl", "module", "-Dtest=ClassName#methodName", "test"]
```
Use `mvnw.cmd` on Windows. The current Surefire documentation scopes its
`ClassName#methodName` example to JUnit 4.x and TestNG. For JUnit 5 or another
provider, use a method selector only after the repository's installed plugin
and provider confirm support.
Do not assume these selectors apply to custom Gradle tasks, Maven Failsafe,
integration-test source sets, parameterized cases, or other JVM runners.
Inspect the build files and task/plugin help first.
## Official documentation
- Gradle wrapper, project task paths, and task options:
https://docs.gradle.org/current/userguide/command_line_interface.html
- Gradle `--tests` filtering and `--test-dry-run`:
https://docs.gradle.org/current/userguide/java_testing.html#test_filtering
- Maven Surefire single-class and method selectors:
https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html

View File

@@ -1,33 +0,0 @@
# Python
Inspect `pyproject.toml`, `pytest.ini`, `tox.ini`, `setup.cfg`, and repository
scripts to identify the environment wrapper and runner. Preserve repository
wrappers such as tox, nox, uv, or Poetry when they establish dependencies or
environment variables.
For direct pytest usage, a file target is:
```text
["python", "-m", "pytest", "path/to/test_file.py"]
```
A single case uses its pytest node id:
```text
["python", "-m", "pytest", "path/to/test_file.py::TestClass::test_name"]
```
Verify the node id before executing:
```text
["python", "-m", "pytest", "--collect-only", "-q", "path/to/test_file.py::TestClass::test_name"]
```
Parameterized cases add their generated id in brackets; copy it from collection
output instead of guessing it. Do not assume a unittest, Django, or custom
runner accepts pytest selectors; use the detected runner's own syntax.
## Official documentation
- pytest invocation, node ids, `python -m pytest`, and `--collect-only`:
https://docs.pytest.org/en/stable/how-to/usage.html

View File

@@ -1,35 +0,0 @@
# Ruby
Inspect `Gemfile`, repository scripts, and runner configuration. Use
`bundle exec` when the repository is Bundler-managed so the selected runner
version and plugins match the project.
For RSpec, a file target is:
```text
["bundle", "exec", "rspec", "spec/path/to/example_spec.rb"]
```
RSpec can select an example or group by a line in the file:
```text
["bundle", "exec", "rspec", "spec/path/to/example_spec.rb:<line>"]
```
Do not apply RSpec syntax to Minitest, Rails test tasks, or custom runners.
For example, Rails' Minitest runner has its own file-and-line form:
```text
["bin/rails", "test", "test/models/user_test.rb:<line>"]
```
Follow the repository's runner-specific command and expected scope.
## Official documentation
- Bundler execution context and its RSpec example:
https://bundler.io/man/bundle-exec.1.html
- RSpec file-and-line selection:
https://rspec.info/features/3-12/rspec-core/command-line/line-number-appended-to-path/
- Rails Minitest file, name, and line selection:
https://guides.rubyonrails.org/testing.html#the-rails-test-runner

View File

@@ -1,40 +0,0 @@
# Rust
Inspect the workspace `Cargo.toml` and the target crate's manifest. Rust's
focused unit scope is usually a package plus a test name; an integration test
file is a named Cargo test target.
For an integration-test target:
```text
["cargo", "test", "-p", "<package>", "--test", "<integration-target>"]
```
List the libtest names in that target without running them:
```text
["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "--list"]
```
Then run one case using the full path printed by libtest:
```text
["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "<full-test-path>", "--exact"]
```
For a library unit test, replace `--test <integration-target>` with `--lib`.
Here the separator is required because the filter, `--list`, and `--exact`
belong to the compiled libtest harness, not Cargo. `--exact` matches only a full
path such as `module::tests::test_name`; a short function name can select zero
tests. Confirm the target name with Cargo metadata or the manifest instead of
deriving it only from a filesystem path.
These libtest arguments do not apply when the target declares
`harness = false`; use that target's own CLI.
## Official documentation
- Cargo package/target selection and test-argument forwarding:
https://doc.rust-lang.org/cargo/commands/cargo-test.html
- libtest filters, `--list`, and `--exact`:
https://doc.rust-lang.org/rustc/tests/

View File

@@ -518,121 +518,6 @@ func TestProjectsAndResourcesSkillCoversDurableContext(t *testing.T) {
}
}
func TestFocusedTestingSkillUsesStackSpecificProgressiveDisclosure(t *testing.T) {
skill, ok := findSkill(t, "multica-focused-testing")
if !ok {
return
}
fm, body, _ := splitFrontmatter(skill.Content)
description := fm["description"]
for _, want := range []string{
"focused or targeted test",
"any user repository",
"Detect the repository's stack and runner first",
"Not for an explicitly requested full-suite run",
} {
if !strings.Contains(description, want) {
t.Errorf("focused-testing description missing trigger text %q", want)
}
}
for _, want := range []string{
"repository Agent configuration",
"dedicated repository script",
"runner-native focused selector",
"Do not guess whether a wrapper",
"forwards separators or positional arguments",
"Never impose",
"`expected_file_count=1` on a runner that does not discover by file",
"read exactly the matching reference",
"Do not borrow a template from another stack",
} {
if !strings.Contains(body, want) {
t.Errorf("focused-testing skill missing stack-neutral rule %q", want)
}
}
// Concrete runner commands belong behind one-level-deep references. The
// body is loaded for every focused-test task; keeping templates out of it
// prevents a Go/Python/Rust repository from inheriting frontend noise.
for _, runnerSpecific := range []string{
"pnpm --filter",
"go test",
"python -m pytest",
"cargo test",
"./gradlew",
"dotnet test",
"bundle exec rspec",
} {
if strings.Contains(body, runnerSpecific) {
t.Errorf("focused-testing body must stay stack-neutral; found %q", runnerSpecific)
}
}
references := map[string][]string{
"references/javascript-typescript.md": {
`["pnpm", "--filter", "<workspace>", "exec", "vitest", "run", "<package-relative-test-file>"]`,
`["pnpm", "--filter", "<workspace>", "exec", "vitest", "list", "<package-relative-test-file>", "--filesOnly"]`,
`["pnpm", "--filter", "<workspace>", "test", "--", "<test-file>"]`,
"exactly one discovered test file",
"https://pnpm.io/cli/exec",
"https://vitest.dev/guide/cli",
},
"references/go.md": {
`["go", "test", "./path/to/package", "-run", "^TestName$", "-count=1"]`,
`["go", "test", "./path/to/package", "-list", "^TestName$"]`,
"not reliably by\nrunning one `_test.go` file in isolation",
"https://pkg.go.dev/cmd/go#hdr-Testing_flags",
},
"references/python.md": {
`["python", "-m", "pytest", "path/to/test_file.py::TestClass::test_name"]`,
`["python", "-m", "pytest", "--collect-only", "-q", "path/to/test_file.py::TestClass::test_name"]`,
"https://docs.pytest.org/en/stable/how-to/usage.html",
},
"references/rust.md": {
`["cargo", "test", "-p", "<package>", "--test", "<integration-target>"]`,
`["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "<full-test-path>", "--exact"]`,
"the separator is required",
"`harness = false`",
"https://doc.rust-lang.org/rustc/tests/",
},
"references/jvm.md": {
`["./gradlew", ":module:test", "--tests", "package.ClassName.methodName"]`,
`["./mvnw", "-pl", "module", "-Dtest=ClassName#methodName", "test"]`,
"JUnit 4.x and TestNG",
"https://docs.gradle.org/current/userguide/java_testing.html#test_filtering",
"https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html",
},
"references/dotnet.md": {
`["dotnet", "test", "path/to/project.csproj", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]`,
`["dotnet", "test", "path/to/project.csproj", "--list-tests", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]`,
"Do not reuse that argv for MTP",
"https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-mtp",
},
"references/ruby.md": {
`["bundle", "exec", "rspec", "spec/path/to/example_spec.rb"]`,
`["bundle", "exec", "rspec", "spec/path/to/example_spec.rb:<line>"]`,
`["bin/rails", "test", "test/models/user_test.rb:<line>"]`,
"Do not apply RSpec syntax to Minitest",
"https://bundler.io/man/bundle-exec.1.html",
"https://guides.rubyonrails.org/testing.html#the-rails-test-runner",
},
}
for path, mustContain := range references {
content, ok := skillFileContent(skill, path)
if !ok {
t.Errorf("focused-testing skill missing supporting file %s", path)
continue
}
for _, want := range mustContain {
if !strings.Contains(content, want) {
t.Errorf("%s missing %q", path, want)
}
}
}
}
func findSkill(t *testing.T, name string) (AgentSkillData, bool) {
t.Helper()
for _, s := range loadBuiltinSkills() {
@@ -644,15 +529,6 @@ func findSkill(t *testing.T, name string) (AgentSkillData, bool) {
return AgentSkillData{}, false
}
func skillFileContent(skill AgentSkillData, path string) (string, bool) {
for _, f := range skill.Files {
if f.Path == path {
return f.Content, true
}
}
return "", false
}
func skillHasFile(skill AgentSkillData, path string) bool {
for _, f := range skill.Files {
if f.Path == path {