feat(roles): implement F098 agent role injection via AGENTS.md#352
Merged
Conversation
dc0647c to
c6f1b6f
Compare
- `.go-arch-lint.yml`: register `infra-roles` component and wire dependency rules - `CHANGELOG.md`: add F098 entry to Unreleased section - `CLAUDE.md`: add two architecture rules for infra components and adapter patterns - `README.md`: add Agent Roles bullet to feature list - `docs/README.md`: add Agent Roles entry under agent-steps section - `docs/reference/error-codes.md`: add USER.INPUT.MISSING_ROLE error code documentation - `docs/user-guide/agent-steps.md`: add full Agent Roles section with examples and validation table - `docs/user-guide/workflow-syntax.md`: document `role` field in agent step syntax reference - `internal/application/conversation_manager.go`: inject role system prompt in ExecuteConversation - `internal/application/conversation_manager_helpers_test.go`: consolidate testResolverWithValues helper - `internal/application/conversation_manager_role_test.go`: add 267-line role injection test suite - `internal/application/conversation_manager_tdd_test.go`: update ExecuteConversation call signatures - `internal/application/conversation_manager_test.go`: add workflowDir parameter to test calls - `internal/application/execution_service.go`: wire role resolution in executeAgentStep and conversation path - `internal/application/execution_service_conversation_step_test.go`: update test signatures - `internal/application/execution_service_role_test.go`: add 504-line role execution test suite - `internal/application/execution_setup.go`: wire SetAgentRoleRepository in service initialization - `internal/application/role_loader.go`: add BuildRoleSystemPrompt helper and nil guard - `internal/application/role_loader_test.go`: remove duplicate resolver helper - `internal/domain/workflow/agent_role.go`: add ErrRoleEmptyContent validation code - `internal/domain/workflow/agent_role_test.go`: update tests for struct field changes - `internal/infrastructure/roles/filesystem_repository.go`: fix cross-platform path traversal check and filter empty search paths - `internal/infrastructure/xdg/xdg.go`: expose AWF agents XDG config dir - `internal/interfaces/cli/validate.go`: add role reference validation with path-traversal guard - `internal/interfaces/cli/validate_role_test.go`: add 416-line CLI validation test suite Closes #351
c6f1b6f to
690bd68
Compare
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
role:field on agent steps that loads anAGENTS.mdfile from a named directory and injects its body as the agent's system prompt, establishing a reusable persona across workflows (roles define who the agent is; skills define what it knows — orthogonal injection channels).awf/agents/→.agents/→$XDG_CONFIG_HOME/awf/agents/→~/.agents/) withAWF_AGENTS_PATHexclusive override for CI/sandbox isolation; cross-client compatible with Cursor/Cline global~/.agents/executeAgentStep,executeResumableAgentCall,ConversationManager.ExecuteConversation) through a singleBuildRoleSystemPrompthelper to prevent divergenceawf validateto report hard errors for missing role directories/AGENTS.md and non-blocking warnings for empty content, files > 500KB, and composed prompts > 10KB; path-traversal patterns rejected at validation timeChanges
Domain
internal/domain/workflow/agent_role.go: AddedErrRoleEmptyContentvalidation code; minor struct refinementsinternal/domain/workflow/agent_role_test.go: Updated tests after struct/code changesApplication
internal/application/role_loader.go: ExtractedBuildRoleSystemPromptshared helper consolidating duplicated role resolution logic; added nil guard afterResolveAgentRoleto prevent panic on(nil, nil)returnsinternal/application/execution_service.go: WiredagentRoleRepofield; role system prompt composed before both single-turn and resumable agent calls viaBuildRoleSystemPrompt; added override warning log whenoptions.system_promptis supersededinternal/application/execution_setup.go: WiredSetAgentRoleRepositoryforConversationManageralongsideExecutionServiceinternal/application/conversation_manager.go: AddedagentRoleRepofield +SetAgentRoleRepository()setter;ExecuteConversationnow acceptsworkflowDirparam and resolves role before state initialization; warns whenoptions.system_promptis overridden by composed promptInfrastructure
internal/infrastructure/roles/filesystem_repository.go: Cross-platform path-traversal fix (checks both/and\unconditionally); filters empty search paths at init timeinternal/infrastructure/xdg/xdg.go: Exposes agents XDG directory for discovery path constructionInterfaces — CLI
internal/interfaces/cli/validate.go: Added full role reference validation — disambiguates dir-exists-without-AGENTS.md from role-not-found; issues structuredErrRoleEmptyContentwarning; path-traversal guard; size and combined-prompt warningsArchitecture
.go-arch-lint.yml: Registeredinfra-rolescomponent with explicit dependency rules; addedinfra-rolestointerfaces-cliallowed importsDocumentation
docs/user-guide/agent-steps.md: New "Agent Roles" section (231 lines) — discovery paths, format, composition with inlinesystem_prompt, explicit path references, dynamic selection, validation table, conversation mode, limitationsdocs/user-guide/workflow-syntax.md: Addedrole:to agent step reference table and example YAML blockdocs/reference/error-codes.md: NewUSER.INPUT.MISSING_ROLEentry with resolution steps and related codesREADME.md: Added "Agent Roles" bullet to feature listdocs/README.md: Linked Agent Roles section in table of contentsCHANGELOG.md: Added F098 entry to Unreleased sectionCLAUDE.md: Added two architecture rules forgo-arch-lint.ymlupdates andStripFrontmatterreuseTests
internal/application/execution_service_role_test.go: 504-line new file — covers role injection in single-turn and resumable paths, composition with inline system prompt, missing role errors, nil repo fallback, dynamic interpolationinternal/application/conversation_manager_role_test.go: 267-line new file — covers composed system prompt passed to provider, role-not-found propagation, nil repo behaviour in conversation modeinternal/application/conversation_manager_helpers_test.go: ConsolidatedtestResolverWithValuesshared helper; updatedinitializeConversationStatecall sites with newcomposedSystemPromptparameterinternal/application/conversation_manager_tdd_test.go: UpdatedinitializeConversationStatecalls to pass composed prompt paraminternal/application/conversation_manager_test.go: UpdatedExecuteConversationcalls with newworkflowDirparameterinternal/application/execution_service_conversation_step_test.go: Added missingworkflowDirparam toexecuteConversationStepcallsinternal/application/role_loader_test.go: Removed formulaic doc comments; aligned with refactored signaturesinternal/interfaces/cli/validate_role_test.go: 416-line new file — covers all validation branches: found, missing, dir-without-AGENTS.md, empty content, path traversal, size warnings, combined-prompt warningTest plan
awf validate workflow.yamlwith a validrole: go-seniorreference reports ✓ and exits 0awf validate workflow.yamlwith a missing role reportsUSER.INPUT.MISSING_ROLEand exits non-zero; a role directory withoutAGENTS.mdemits the correct disambiguation messageawf run workflowwithrole: go-seniorinjects AGENTS.md body as system prompt (verify via--output verboseor provider debug logs); combining withsystem_prompt:prepends role content separated by a blank linemake test && make lintCloses #351
Generated with awf commit workflow