Phase 3 edits the `.agent` file directly using the Edit tool. No intermediate markdown conversion step. After editing, validate and publish the authoring bundle.
---
## Pre-Flight: Verify Action Target Availability
Before making any `.agent` file edits, verify that all action targets actually exist and are registered in the org.
**Step 1 -- Extract all action targets from the `.agent` file:**
**Step 2 -- Query GenAiFunction records in the org:**
```bash
sf data query --json -q "SELECT DeveloperName, MasterLabel, InvocableActionDeveloperName FROM GenAiFunction WHERE IsActive = true" -o <ORG_ALIAS>
```
**Step 3 -- Compare and flag missing targets:**
```bash
# For flow:// targets
sf flow list -o <ORG_ALIAS> --json | python3 -c "import json,sys; flows=[f['ApiName'] for f in json.load(sys.stdin)['result']]; print('\n'.join(flows))"
# For apex:// targets
sf data query --json -q "SELECT Name FROM ApexClass WHERE Name IN ('ClassName1','ClassName2')" -o <ORG_ALIAS>
```
**Step 4 -- Present options to user if targets are missing:**
1.**Deploy missing targets first** -- Use `Section 17 of /agentforce-generate` to generate stubs, then `Section 18 of /agentforce-generate` to deploy
2.**Remove unresolvable actions** -- Delete from `.agent` file and focus on routing/instruction improvements
3.**Register via Agent Builder UI** -- For targets that exist but aren't registered as `GenAiFunction`
4.**Proceed anyway** -- If the planned fix only touches routing logic or instructions
**Guideline:** If 50%+ of action targets are missing or unregistered, pivoting to routing and instruction fixes is usually the most pragmatic path.
The `.agent` file uses Agent Script -- an indentation-sensitive DSL that compiles to Agentforce metadata. Spaces are the portable standard; examples here use 4 spaces per level:
| `Agent Configuration Gap` | Action not called | `subagent <name>: reasoning: actions:` and `reasoning: instructions:` | Add action definition under `actions:` and mention it in `instructions:` |
| Yes | No | Deploy/register: use `Section 18 of /agentforce-generate` or register via Agent Builder UI |
| No | N/A | Scaffold first: use `Section 17 of /agentforce-generate` to generate stub, then deploy |
| Can't deploy now | N/A | Pivot to routing fixes: remove action from `.agent`, focus on instructions and transitions |
---
## Principles for Effective Subagent Instructions
Good instructions are specific, imperative, and action-named. Poor instructions are persona descriptions or generic guidance reused across subagents.
1.**Name the action explicitly** -- "Use `@actions.schedule_test_drive` to book the appointment" not "help the user book"
2.**State the pre-condition** -- "Only handle scheduling after the customer's name and email have been collected"
3.**State what to do after** -- "After scheduling completes, confirm the date/time and transition to follow_up"
4.**Scope tightly** -- "This subagent handles test drive scheduling only. For vehicle specs or pricing, do not answer -- the user should be routed to general_support"
5.**Keep persona out of instructions** -- persona belongs in `system: instructions:` (agent-level), not per-subagent reasoning instructions
6.**One responsibility per subagent** -- if the instruction covers 3 distinct tasks, split into 3 subagents
**Before / after example** (identical instructions -> distinct instructions):
*Before (generic persona text, same across all subagents):*
| Collect the customer's name, email address, and phone number using @actions.collect_customer_info.
| Do not proceed until all three fields are provided.
| After collection, confirm the details back to the customer.
actions:
collect_info: @actions.collect_customer_info
description: "Capture customer contact details"
set @variables.customer_name = @outputs.name
set @variables.customer_email = @outputs.email
proceed: @utils.transition to @subagent.schedule_test_drive
description: "Move to test drive scheduling after info collected"
available when @variables.customer_name != ""
```
---
## Regression Prevention
When editing subagent instructions, follow these principles:
1.**Establish a baseline BEFORE editing** -- Run the test utterance 3 times before making changes. Record the pass rate.
2.**Make minimal, targeted edits** -- Change only the specific instruction line that addresses the identified issue. Do NOT expand terse instructions into verbose ones unless the terse version was causing a specific documented failure.
3.**Avoid instruction expansion** -- Adding more text to instructions does NOT always help. Prefer:
- Adding a single action reference: "Use `@actions.X` to look up..."
- Adding a single constraint: "Do not proceed until the customer provides..."
- Adding a single routing directive: "After completing, transition to @subagent.Y"
4.**Test immediately after each edit** -- Run the same test utterances. If pass rate drops, revert the change immediately.
5.**One fix per publish cycle** -- Do not batch multiple instruction changes into a single publish.
6.**Check cross-subagent dependencies before editing** -- Before changing Subagent A, identify variable dependencies, transition chains, and shared variable mutations:
```bash
grep -n 'set @variables\.' "$AGENT_FILE"
grep -n 'with .* = @variables\.' "$AGENT_FILE"
grep -n '@utils.transition to @subagent\.' "$AGENT_FILE"
```
7.**Test adjacent subagents after each fix** -- Include at least one cross-subagent test to confirm the fix didn't cause spillover routing.
8.**Verify start_agent routing after subagent removal** -- If removing a dead hub or merging subagents, verify `start_agent > reasoning > actions:` still has transition actions to all remaining subagents.
---
## Apply Fixes
**Step 1 -- Read the current .agent file** using the Read tool. Locate the specific `subagent` block that needs changes.
**Step 2 -- Edit the .agent file directly** using the Edit tool. Edit only the specific lines that need to change. Common edit patterns:
- **Subagent description** (for misroute fixes): Change `description:` text
After editing the `.agent` file, use this deployment chain. **Never update `GenAiPluginInstructionDef` or other agent metadata directly** -- always edit the `.agent` file and re-deploy.
```bash
# Step 1: Validate (dry run)
sf agent validate authoring-bundle --json --api-name <AGENT_API_NAME> -o <org>
```
If validation fails: fix syntax errors, deploy missing targets, or resolve duplicate names.
```bash
# Step 2: Publish (compiles, deploys metadata, and activates)
sf agent publish authoring-bundle --json --api-name <AGENT_API_NAME> -o <org>
```
**If publish fails**, use the deploy + activate fallback:
```bash
# Step 3a: Deploy the bundle
sf project deploy start --json --metadata "AiAuthoringBundle:<AGENT_API_NAME>" -o <org>
# Step 3b: Activate
sf agent activate --json --api-name <AGENT_API_NAME> -o <org>
```
> **Warning: deploy + activate is an incomplete fallback.** `sf project deploy start` stores the bundle metadata but does **NOT** propagate subagent-level `reasoning: actions:` blocks to live `GenAiPluginDefinition` records. Always verify with `--authoring-bundle` preview.
**Never use the Tooling API to patch `GenAiPluginInstructionDef` or other BPO objects directly.**
---
## Verify
**Immediate** -- run the Phase 2 scenarios that returned `[CONFIRMED]` before the fix. All should now return `[NOT REPRODUCED]`. Use `--authoring-bundle` to get trace-level verification:
Run from the Salesforce project directory. `start` needs an action mode with `--authoring-bundle`; substitute `--use-live-actions` when the fix depends on real action results.
After applying fixes, re-run safety review on the modified `.agent` file. Optimization fixes can inadvertently introduce safety regressions:
- Relaxing `available when` guards may expose actions that should be gated
- Expanding subagent descriptions may cause the agent to handle out-of-scope requests
- Changing instructions to be more permissive may weaken guardrails
- Adding literal instructions with tool names may bypass safety boundaries
**Run the safety review** from `Section 15 of /agentforce-generate` (Identity, User Safety, Data Handling, Content Safety, Fairness, Deception, Scope). Focus especially on:
1.**Scope boundaries** -- Did the fix widen the agent's scope beyond what's appropriate?
2.**Guard conditions** -- Did relaxing `available when` expose sensitive actions?
3.**Instruction safety** -- Do new/modified instructions maintain appropriate guardrails?
4.**Escalation paths** -- Are escalation paths still intact after subagent restructuring?
**If any new BLOCK finding is introduced by the fix:** revert and find an alternative fix. Do NOT deploy an agent with new safety violations.
---
## Update Testing Center Test Cases
After fixing issues, create or update test cases in Testing Center format:
```yaml
# tests/<AgentApiName>-regression.yaml
name: "<AgentApiName> Regression Tests"
subjectType: AGENT
subjectName: <AgentApiName>
testCases:
- utterance: "<exactutterancefromPhase2scenario>"
expectedTopic: <subagent_that_should_handle_this>
expectedActions:
-<action_that_should_fire>
- utterance: "<anotherfailingutterance>"
expectedTopic: <expected_subagent>
expectedOutcome: "Agent should <expectedbehaviordescription>"
```
**Key format rules:**
-`expectedActions` is a **flat string list**: `["action_a"]`, NOT objects
-`subjectName` is the agent's `DeveloperName` (API name without `_vN` suffix)
-`expectedOutcome` uses LLM-as-judge evaluation
**Deploy and run:**
```bash
sf agent test create --json \
--spec tests/<AgentApiName>-regression.yaml \
--api-name <AgentApiName>_Regression \
--force-overwrite \
-o <org>
sf agent test run --json \
--api-name <AgentApiName>_Regression \
--wait 10 \
--result-format json \
-o <org> | tee /tmp/regression_run.json
# ALWAYS use --job-id, NOT --use-most-recent which is broken