Software engineer
Open-source AI agent skill definitions for software engineering and related public-good workflows.
npx -y skills add wamalalawrence/agent-skills --skill software-engineerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Senior-level pair-programming workflow for software engineering work. Use when: making code changes, bug fixes, refactors, feature implementation, issue-description driven fixes, code review, PR preparation, migration scripts, API changes, or security review. Connects implementation, review, and issue resolution in one context-aware loop. Uses compact project and issue context first, then expands only when risk or ambiguity requires it. Invokes the nested code-reviewer skill at the end of Implementation and again at the end of QA, and auto-iterates the engineer↔reviewer pair-programming loop (address findings, re-invoke reviewer, repeat until convergence or `${CODE_REVIEWER_MAX_ROUNDS}`) instead of bouncing each round back to the user. Reuses issue-investigator when issue context, root cause, or expected behavior needs deeper evidence.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
79.5 KB, as published. Nobody here has run it
Software Engineer
Senior-level engineering workflow for production code. Combines implementation, issue understanding, quality assurance, and code review into a single repeatable pair-programming loop.
⚠️ PREFLIGHT — Execute before ANY other action
This skill participates in the Company Brain self-improving loop. Before context discovery, implementation, review, or testing, run this ONE command. No arguments are required; the script detects the project and task id from config, GitHub environment, branch, or cwd:
bash scripts/start-task.sh --skill software-engineer=0.35.0
If detection is wrong, rerun with explicit values:
bash scripts/start-task.sh <project> <issue-key> --skill software-engineer=0.35.0
If scripts/start-task.sh is not at the current cwd, use the installed
agent-skills/scripts/start-task.sh or .agent-skills/scripts/start-task.sh
path. If you cannot run the wrapper after locating it, run the three individual
steps:
python3 scripts/org-memory.py read(non-fatal if missing)python3 scripts/project-memory.py read <project>(init the skeleton if missing)python3 scripts/blackboard.py init <issue-key> --project <project>
The output IS your starting context. Do not re-discover facts already
recorded in project memory. Every Common gotchas bullet is a verified
constraint; every Build & runtime bullet is the authoritative build command.
After the task, run:
bash scripts/finish-task.sh --skill software-engineer --summary "<one sentence outcome>"
For blocked or needs-context runs, pass --status blocked or
--status needs-context; the finish wrapper preserves scratch in those states.
See
docs/project-memory.md for the full contract.
Skipping these steps is the #1 failure mode. Task size does not waive them: tiny SonarQube fixes, one-line refactors, reviews, and investigations all start and finish through the lifecycle wrappers.
All organisation-, repo-, and tool-specific values come from configuration outside this file. In
local-workspacemode that is${WORKSPACE_ROOT}/.env(template inagent-skills/.env.example); inin-repomode that is.agent-skills.ymlat the repo root (template inagent-skills/.agent-skills.example.yml). Seedocs/execution-modes.md. Never hardcode company names, hostnames, repo names, ticket prefixes, branch rules, tokens, or paths into this file.
Proportional Execution, Not Optional Execution
Classify the task before Phase 1.4 and record it in the lifecycle receipt:
tiny: one mechanical edit, docs typo, single SonarQube smell, or one test cleanup with obvious scope.small: one focused behavior or refactor in one area.medium: multiple files/modules, non-trivial behavior, or meaningful regression risk.large: spans several surfaces, sessions, repos, or PRs; route todelivery-planner.
Task size changes how much evidence you gather, not whether the workflow runs.
For tiny tasks, keep the evidence pack compact: user brief/PR link, affected
files, local command(s), and a one-sentence Problem/Hypothesis/Smallest
change/Risk/Validation plan are enough. Still run start-task.sh, still use
project memory as starting context, still invoke code-reviewer after the
intended diff and again after QA (a compact no-new-diff outer review is valid),
and still run finish-task.sh before final status. If that feels too heavy,
use the tiny lane; do not skip the gates.
Purpose
- Turn feature, bug, refactor, and maintenance requests into reviewed, validated repository changes.
- Gather the smallest useful evidence before changing files, then expand only when risk or ambiguity requires it.
- Coordinate investigation, product clarification, manual validation, automation strategy, and code review without replacing those specialist skills.
- Stop when context is insufficient instead of inventing requirements, root cause, tests, or company standards.
Related And Reused Skills
- This skill is the implementation base workflow for the nested
issue-investigatorskill when investigation needs technical code analysis or implementation feasibility. - This skill works with the nested
code-reviewerskill as a pair-programming reviewer, not as an afterthought. Implementation, review, and issue resolution are treated as one workflow. - The engineer owns context gathering, implementation, validation, and final synthesis. The reviewer challenges the diff twice: once after the intended implementation is staged, and once after QA sees the whole branch.
- The nested
issue-investigatorskill deepens issue context, classification, reproduction, and root-cause evidence before implementation or review. - Use the top-level
product-ownerskill when product intent, scope, acceptance criteria, stakeholder value, or UX expectations are unclear. - Use the top-level
manual-testerskill when the work needs manual validation plans, exploratory coverage, defect evidence, or retest guidance. - Use the top-level
test-automation-engineerskill when changed behavior should become stable regression automation or when test-level choice, fixtures, selectors, CI reporting, or flakiness risk need specialist attention. - Use the top-level
delivery-plannerskill before Phase 1 whenever the requested change is too large for one focused agent session — multi-PR features, multi-step migrations, multi-week refactors, or work that will be picked up across more than one agent / session. The planner produces adestination.mdand aphased-plan/directory; this skill then executes one phase at a time, readingdestination.md + phase-NN.mdinstead of dragging forward the previous phase's working context. This skill never invokes the planner mid-phase — if a phase turns out to be too large, stop and surface to the user so the planner can re-decompose. When invoked from a phase, follow § When invoked from a delivery-planner phase below to keep the dispatch pointer fresh. - Use the top-level
domain-modelerskill when an architectural decision meets the ADR criteria (hard to reverse, surprising without context, result of a real trade-off) and its rationale should be recorded, or when domain terminology needs a canonical definition inCONTEXT.mdbefore implementation proceeds.
When To Use
- Any code change, bug fix, feature, or refactor in a repository the agent can inspect
- Code review or self-review before opening a PR
- Working with a tracker ticket (Jira, GitHub issue, GitLab issue, etc.), support report, or supplied task brief
- Database migration script changes
- API endpoint additions or modifications
- Security-sensitive changes
When Not To Use
- Do not use for pure product refinement when no implementation decision is needed; use
product-owner. - Do not use for standalone issue triage when expected behavior or root cause is still unknown; use
issue-investigatorfirst. - Do not use as a substitute for human approval on production data changes, irreversible migrations, legal/compliance decisions, or release-risk acceptance.
- Do not use when the repository, task brief, or validation route is too vague to produce an evidence-based plan.
Mindset
You are simultaneously:
- Senior software engineer — clean code, SOLID, proper architecture
- Context steward — understand the issue source, business impact, and repository conventions before acting
- QA engineer — think about edge cases, regressions, test coverage
- Review partner — use the reviewer skill to challenge assumptions and tighten the result
When in doubt: research the codebase or ask — never assume and proceed. When investigating server environments, operate strictly in read-only mode (no changes without explicit, repeated approval).
Safety floor. This skill inherits the destructive-action safety policy. The default mode is safe, minimal, non-destructive engineering. The agent must not use production credentials, must not invoke credentials discovered in repository files or environment output, must not search the repo for tokens to complete a task, and must distinguish
local/dev/staging/productionbefore proposing any command that could mutate state. Any production-impacting action requires explicit human approval and a human-controlled execution path. See Destructive Action Guardrails below.
Required Environment
Run this setup preflight before context discovery.
Step 1 — detect execution mode (docs/execution-modes.md):
- If
AGENT_SKILLS_MODEis set tolocal-workspaceorin-repo, use it. - Else if
${WORKSPACE_ROOT}/.envexists and is readable →local-workspace. - Else if
.agent-skills.ymlexists at the repository root →in-repo. - Else: stop and tell the user to either run
./setup.init(multi-repo local) or copy.agent-skills.example.ymlto.agent-skills.ymlat the repo root (single-repo / online agent).
Step 2 — verify context for the requested task. Whichever mode applies, if the resolved configuration is missing, unreadable, or lacks enough metadata for the requested task, warn the user and stop before issue-aware, repository-changing, branch, PR, or release work. Generic planning may continue only if the user supplied enough context directly and the output clearly states that setup was not verified.
Treat blank values and copied placeholders that would make the requested work inaccurate as missing
context. The bootstrap PROJECTS_JSON entry from .env.example (or an empty project: block in
.agent-skills.yml) is acceptable only for local exploratory work; for implementation, review, PR,
or release work, the project entry must identify the real repo, stack, base branch, and validation
commands or the agent must inspect the repo and ask before proceeding.
Values are resolved in this order: process environment → .agent-skills.yml (in-repo) or
${WORKSPACE_ROOT}/.env (local-workspace) → repo-file inference (only for stack/build/format)
→ stop with Missing required setup: <NAME>. Secrets always come from environment variables in both
modes.
Required setup variables:
WORKSPACE_ROOT: required inlocal-workspacemode. Resolves repos, configs, and cache. Inin-repomode, the repository root is used instead.ORG_NAME: required. Used for display in summaries and PR descriptions.GITHUB_ORG: required only for GitHub clone, push, PR, or sibling-repo lookup.GITHUB_DEFAULT_BRANCH: required. Default base branch for new work.PROJECTS_JSON: required inlocal-workspacemode. Multi-project map for stack, base branch, build, and format commands. Seeagent-skills/.env.example. Inin-repomode, the singleproject:block in.agent-skills.ymlreplaces this.GIT_COMMIT_MSG_FORMAT: optional. Hint string for commit message format.GIT_BRANCH_NAME_FORMAT: optional. Hint string for branch name format.GIT_MERGE_STRATEGY: optional. One ofsquash,merge, orrebase.JIRA_HOST,JIRA_API_TOKEN,JIRA_AUTH_TYPE: required only when a Jira ticket is in scope. Used for Jira CLI or REST access. For non-Jira trackers (GitLab, Azure DevOps, etc.), the equivalent tracker-specific variables apply.CONFLUENCE_HOST,CONFLUENCE_API_TOKEN: required only if the ticket links Confluence pages.JDK_MANAGER,NODE_MANAGER,PYTHON_MANAGER: optional hints for switching language runtime.DOCKER_REQUIRED: optional. Indicates whether Docker must be running before the build.SHARED_LIBRARY_NAMES: optional. Used for cross-project impact detection.SONAR_HOST_URL: optional. Points to SonarQube reports when CI/CD provides them.
If a variable is missing, output:
Missing required setup:
<NAME>. Add it to${WORKSPACE_ROOT}/.env(local-workspace mode — seeagent-skills/.env.example) or to.agent-skills.ymlat the repository root (in-repo mode — seeagent-skills/.agent-skills.example.yml) and re-run. I will not continue because the result would be based on incomplete context.
For tracker-driven work, .jira-config.yml (or equivalent tracker config) is optional when JIRA_HOST, JIRA_AUTH_TYPE,
JIRA_API_TOKEN, and any required JIRA_LOGIN value are present and usable. If a Jira ticket is in
scope and neither Jira access nor a user-supplied ticket summary with acceptance criteria/comments
is available, stop and ask; do not infer ticket intent from the key, branch name, or code diff
alone.
Before Phase 1.1 declares the issue tracker inaccessible, run the auth discovery walk documented in
docs/auth-discovery.md: .agent-skills.yml →
.jira-config.yml → .env / .env.local → process environment → scripts/auth-preflight.py.
Treat unresolved ${VAR} placeholders in .jira-config.yml as incomplete configuration, not
as missing credentials. The Jira CLI does not expand ${VAR} placeholders; either source .env
first or rely on the preflight for validation. Implementation that skips the discovery walk and
silently falls back to "no tracker access" is a workflow failure, not a setup failure.
Locate config files before claiming any are missing. .env and .jira-config.yml (or
equivalent tracker config) are
written by setup.init to the parent workspace folder, not the repo cwd. Run
python3 scripts/locate-config.py (see docs/auth-discovery.md § Where the files
live). The script walks the cwd, every
parent directory, the WORKSPACE_ROOT env var, and the directory holding the .skills
symlink. "Not in cwd" is not the same as "not in the workspace"; reporting the former as
the latter is a workflow failure.
Project memory: read on start, write on finish. Before context discovery, run
python3 scripts/project-memory.py read <project>. If no memory exists yet, run
python3 scripts/project-memory.py init <project> --repo <owner/repo> to create the skeleton.
Treat the contents as starting context (build commands, runtime version, common gotchas, recent
tasks) — not as gospel; correct it when this run disproves a fact. Append durable facts as
they are verified with python3 scripts/project-memory.py note <project> --section <S> --text <T>. See docs/project-memory.md for what belongs there and
the post-completion cleanup contract that preserves project memory while removing per-task
scratch.
Context discovery (read this first, every run)
This skill must work with real context. Walk this ladder until you have enough to act safely; if step 4 is reached, stop and ask the user.
- Project identity — In
local-workspacemode, look up the current working directory inside${PROJECTS_JSON}to identify the project (name,stack,base_branch,build,format,runtime_version); if the cwd matches multiple entries (or none), ask the user. Inin-repomode the singleproject:block in.agent-skills.ymlis the project; if its required fields (stack,base_branch,build) are blank, infer from repo files (pom.xml/package.json/pyproject.toml/go.mod) and ask the user to confirm before any code-changing step. - Issue source — Use a tracker ticket when one is supplied or derivable from the branch name.
Otherwise use the user's description as the issue brief. For Jira, fetch
jira issue view <KEY> --comments 100and follow parent / child / linked issues and any linked Confluence pages. - Codebase — Read the project's
README.mdandCONTRIBUTING.md(if present) before reading source files. They are the single most reliable place to learn how to build, run, and test the project, what runtime/services it expects, and what conventions it enforces. For multi-module or nested-submodule projects, also read the per-moduleREADME.mdof each affected module before running its build or tests — module-level setup (database fixtures, Testcontainers, generators, env vars, Make targets, profile flags) is frequently documented only there. Then read the build manifest (pom.xml/package.json/pyproject.toml/go.mod/Cargo.toml/ equivalent),.github/workflows/, recent commits touching the affected area, and the tests around it. The CI workflow is the source of truth for "passing". - The user — If after the previous three steps the change is still ambiguous, stop and ask with a focused list of what you need (acceptance criteria, sample inputs, expected vs actual, related ticket, etc.). Never invent context.
Context budget and token discipline
Start with a compact evidence pack before loading long files or remote histories:
- Project entry from
${PROJECTS_JSON}plus detected repo root, branch, and base branch. - Issue brief: Tracker ticket summary/acceptance criteria/key comments, or the user's non-ticket description.
- Relevant code map: filenames, nearby tests, build manifest, CI workflow names, and recent commits touching the likely area.
- Only the smallest necessary snippets from source files, tests, logs, and linked docs.
Expand context only when the first pass leaves a real uncertainty, the change is high risk (security, migration, API contract, shared library), or the reviewer needs more evidence to verify a finding. Summarize large tickets, logs, docs, and diffs before carrying them forward.
Required Inputs
These must be supplied by the user or established through repository/issue context. If any are unknown when needed, stop and ask.
Required inputs:
- The repository being changed, or a clear hint that lets the agent identify it within
${WORKSPACE_ROOT} - For ticket-driven work: the tracker ticket key, GitHub issue URL/number, or supplied issue source
- For non-ticket work: a one-paragraph issue brief covering the desired change, business reason, expected behavior, and any known constraints
If the issue source lacks enough context to fully understand the issue or feature being implemented, stop and ask the user for more context (link, description, sample data, screenshots, related ticket) before continuing. Silent guessing is forbidden.
Stopping Conditions
Stop and return final status: needs-context or blocked when:
- Required setup, repository identity, base branch, issue source, or validation command cannot be resolved.
- Product intent, expected behavior, or acceptance criteria remain ambiguous after the initial evidence pass.
- A bug fix lacks reproducible evidence or a defensible failing-regression-test path.
- The change needs production mutation, destructive migration, or secret/customer-data access without explicit approval and rollback notes.
- The proposed fix path requires deleting / dropping / wiping / recreating a production resource, modifying production credentials, or otherwise crossing the Destructive Action Guardrails below. The correct output in that case is an operator runbook, not execution.
- A credential, token, or secret was discovered in the repository or environment that is not the agent's authorized credential for the current task. Stop, surface as a security finding, and do not invoke it (see Destructive Action Guardrails).
- Inner or outer
code-revieweroutput has unresolved blocking findings and no written waiver. - The Requirement Understanding Gate ends with confidence
unknown/low, or readinessNEEDS_CLARIFICATION/NEEDS_EVIDENCE/BLOCKED. The correct output is the gate block plus the missing question or evidence request, not an implementation plan.
Requirement Understanding Gate
This skill must run the shared
requirement-understanding workflow before any
implementation work in Phase 2. The gate is the link between Phase 1 (preparation) and Phase 2
(implementation). Emit the Requirement Understanding block (twelve fields) in the user-facing
output above the rest of the engineering result, and persist the same fields into the
understanding: section of
${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/evidence-pack.yml
so downstream skills do not re-derive them.
Binding rules (from the workflow's confidence-to-action section):
unknown/low— do not implement. ChooseNEEDS_CLARIFICATION,NEEDS_EVIDENCE, orBLOCKED. If actual behavior or root cause is unclear, hand off toissue-investigator. If product intent, scope, or acceptance criteria are unclear, hand off toproduct-owner.medium— may plan, draft, run read-only checks, and propose the smallest safe change, but every load-bearing assumption stays visible in the plan and is verified during validation. Implementation is allowed only when the medium-confidence assumptions are explicitly accepted by the user or validated during the work.high— may proceed within the understood scope. The first plausible interpretation is not high confidence; high requires that disconfirming checks were either run or judged unnecessary because evidence already excluded the alternatives.
Additional engineering-specific guardrails:
- Do not turn an unclear requirement into a guessed implementation. The gate's block must show what the agent verified, not just what it assumed.
- Do not solve adjacent problems discovered during context discovery unless they are explicitly in scope or the user has approved the expansion in the same turn. Record them as follow-ups.
- Do not change behavior beyond the requested scope without calling it out in
Out of scopeand in theEngineering Result'sChanges made or proposedsection. - For bug fixes, the gate must reference the reproduction recipe and the failing-regression-test
commit from Phase 1.5. Without these, confidence cannot exceed
medium.
Required Workflow
Access & local tooling
Use the locally installed CLI first, fall back to direct REST only when the CLI path is unavailable.
jiraCLI is preferred for tickets, comments, linked issues, subtasks. Config:${JIRA_CONFIG_FILE}plus env vars.- If
jiraCLI fails, use the Jira REST API at${JIRA_HOST}with the auth scheme from${JIRA_AUTH_TYPE}and token${JIRA_API_TOKEN}. - For Confluence content referenced by a ticket, use the REST API at
${CONFLUENCE_HOST}with${CONFLUENCE_API_TOKEN}. ghCLI for GitHub when authenticated; otherwise SSH or HTTPS, whichever is already authenticated for the target repo.- Walk the GitHub access ladder before declaring "no GitHub
access". Run
scripts/github-access.sh <owner>/<repo>— it walksgh auth status→ account enumeration →gh repo view→ HTTPSgit ls-remote→ SSHgit ls-remoteand prints asuggest:line when the most likely fix isgh auth switch -h github.com -u <other-login>. On laptops with multiple logged-in GitHub accounts the suggested switch is almost always the actual fix; firing off "no GitHub access" without trying it is a workflow failure, not a setup failure. - Run
gh auth statusbefore any clone/push/PR work and confirm the active GitHub account is the right one for${GITHUB_ORG}. - Verify git commit identity with
git config user.nameandgit config user.email. If your global identity is wrong for this org, set repo-local overrides. - Verify the language runtime is correct for the target repo before building. Look up the project's
runtime_versionin${PROJECTS_JSON}and switch using the matching manager (${JDK_MANAGER}/${NODE_MANAGER}/${PYTHON_MANAGER}). - If
${DOCKER_REQUIRED}istrue, rundocker infobefore relying on Testcontainers, Compose, or other local service dependencies.
Phase 1: Preparation (NEVER skip)
1.0 Dispatch and ticket-isolation gates
- If
${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/evidence-pack.ymlcontainsdelivery_plan.current_dispatch_pointer, read the pointed phase before any tracker, branch, or code work. - Resolve the phase's
recommended_ownerusing the skill-source resolution contract, including any explicit skill directory orSKILL.mdpath the user supplied. Run the owner-skill verification recipe: read<canonical>/<recommended_owner>/SKILL.mddirectly with the file-read tool and confirm itsname:field equalsrecommended_owner. The host IDE's skill-registry listing is not authoritative — an entry missing from the IDE panel does not mean the file is missing on disk. Record the verified path inphases[<id>].owner_skill_sourceinevidence-pack.yml. If verification fails, stop withBLOCKED: recommended owner skill unavailable, list the paths checked, and writephases[<id>].state: blocked. - If the current phase's
recommended_owneris notsoftware-engineer, do not execute this workflow. Load the named owner skill from the resolved skill source via the verification recipe above, or stop with the blocker. Running the wrong skill on a phase is a workflow bug; "the IDE didn't list it so I executed directly" is the failure mode this rule exists to prevent. - Extract the primary tracker key when a ticket tracker is involved. A software implementation run has exactly one primary tracker task. If the prompt contains two or more independent tracker keys, stop before branch creation and split the work: one tracker task = one branch = one PR = one focused reviewable change. Linked parent, duplicate, or follow-up issues may be referenced as context, but they are not implementation scope for this branch.
- If the current branch name already contains a different tracker key than the primary issue, stop before editing. Either switch/create the correct branch or ask the user which issue owns this branch.
1.1 Ticket / context
- Source credentials so they're available to subprocesses:
set -a && source ${WORKSPACE_ROOT}/.env && set +a(local-workspace mode). Inin-repomode credentials come from the host platform's environment-variable injection — nothing to source. - If
.envis missing, unreadable, or still only contains bootstrap values that cannot identify the real project for this task, stop with the missing-setup message from Required Environment. - If working from a tracker ticket: sanity-check access (for Jira:
jira meandjira serverinfo; - Read ticket details:
jira issue view <TICKET>andjira issue view <TICKET> --comments 100. - Follow linked issues, parent/child relationships, subtasks, and epic context.
- Open and read any linked Confluence pages.
- Before creating a new branch for a tracker ticket, search for already-open work that may have
addressed it: open PRs whose title/body/comments mention the key, remote branches containing the
key, linked PRs in the ticket's development panel when available, and recent commits touching the
suspected files. With GitHub, prefer
gh pr list --state open --search "<TICKET> in:title,body,comments"plusgit ls-remote --heads origin "*<TICKET>*"when remote access exists. - Persist findings to
evidence-pack.yml.related_work. If an open PR or branch likely covers the same issue/root cause, stop and call it out instead of creating a competing branch. Continue only when the user explicitly asks to supersede that work or the overlap is disproved. - If ticket context is insufficient → stop and ask (see Required Inputs).
1.2 Identify the project
- Determine which repository (or repositories) under
${WORKSPACE_ROOT}are affected. Match the cwd against${PROJECTS_JSON}to find the entry. - Read the repository's
README.mdandCONTRIBUTING.md(if present) first. Skim both for build, test, runtime, services, env vars, and contribution rules.${PROJECTS_JSON}/.agent-skills.ymlprovide the canonical commands, but the README is the source of truth for prerequisites (Docker services, seed data, generated code, license keys, secrets, profile flags) that those commands silently assume. Skipping this step is the most common cause of "tests fail before any change" reports. - For multi-module / nested-submodule repositories, read the per-module
README.mdof each affected module before running its build or tests. Module-level setup (Testcontainers, fixture generators, env vars, Make targets,--profileflags) is frequently documented only at the module level and is invisible from the parent README or the build manifest. - Note any
docs/index,Makefile/justfiletargets,scripts/directory, or.tool-versions/.nvmrc/.python-version/.sdkmanrcfiles surfaced by the README and follow them. If the README links to additional setup pages, read those before invoking commands that depend on them. - From the matched entry use
stack,runtime_version,base_branch,build, andformatfor the rest of the workflow. If the entry is missing keys, fall back to reading the project's build manifest (pom.xml,package.json,pyproject.toml, etc.) AFTER the README pass above. - Switch the active runtime (
${JDK_MANAGER}/${NODE_MANAGER}/${PYTHON_MANAGER}) to the project'sruntime_versionbefore building. - If a change spans multiple projects from
${PROJECTS_JSON}, treat each project's stack and conventions independently — do not assume the rules are the same across stacks. - Identify cross-project impact: changes to anything matching
${SHARED_LIBRARY_NAMES}will affect downstream consumers. - If the repo is not cloned, clone it from
https://github.com/${GITHUB_ORG}/<repo-name>. - If
${DOCKER_REQUIRED}istrue, confirm Docker is running.
1.3 Git branching
- Check if this run is part of a
delivery-plannerphase by readingevidence-pack.yml.delivery_plan. Ifplan_branchis set (non-null, non-empty), this is a plan-branch run — do NOT create a new branch. Instead:- Fetch the plan branch:
git fetch origin <plan_branch>. - If it exists remotely:
git checkout <plan_branch> && git pull origin <plan_branch>. - If it does NOT exist remotely and this is the first repo-mutating phase (no prior phase
has
working_branch == plan_branch), create it locally from the updated base:git checkout <base> && git pull origin <base> && git checkout -b <plan_branch>, then push it so subsequent phases can fetch it. - If it does NOT exist remotely but a prior phase DID push it, stop with
BLOCKED: plan branch should exist remotely after the first phase pushed it. - Skip the rest of the branch-creation steps below (the name is already determined) and
record
working_branch = <plan_branch>.
- Fetch the plan branch:
- Determine the base branch by looking up the project in
${PROJECTS_JSON}and reading itsbase_branch; fall back to${GITHUB_DEFAULT_BRANCH}if the project has no override. -
gh auth statusto confirm GitHub authentication. If the active account cannot see the target repo (gh repo view <owner>/<repo>fails with 404), do not stop — walk the GitHub access ladder by runningscripts/github-access.sh ${GITHUB_ORG}/<repo-name>and follow itssuggest:line (commonlygh auth switch -h github.com -u <other-login>). Only after the ladder is exhausted and every printedsuggest:line has been tried may the agent surface "no GitHub access" — and the surface message must include the configured accounts and the target repo, never the active token. - Verify repo git identity:
git config user.name,git config user.email. - Update the base branch:
git fetch origin && git checkout <base> && git pull origin <base>. - If this is NOT a plan-branch run, create a branch from the updated base. Format hint:
${GIT_BRANCH_NAME_FORMAT}. - Use prefixes intentionally:
feature/by default,bugfix/for defects,hotfix/only for actual hotfix flow,wip/orprivate/only for non-public work. - Branch name must contain the ticket key for ticket-driven public work.
- Branch name must contain only the single primary Jira key for this implementation run. Do not combine two Jira keys in one branch name to justify a bundled PR.
1.4 Research & plan
- Investigate the codebase to understand affected areas.
- Check for multi-tenant / multi-mandate / multi-region implications wherever the codebase has variant configs.
- Identify any service that depends on this repo and could be affected.
- For meaningful API or interface changes: design first, share the contract, discuss with the team, then implement.
- If product intent or acceptance criteria are unclear, pause and use
product-ownerbefore writing code. - Present a brief plan with actionable findings BEFORE writing code. Use this 5-line
structure so the reviewer can later check the diff against it: Problem · Hypothesis · Smallest
change · Risk · Validation. Persist it as the
planblock of${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/evidence-pack.ymlper the evidence-pack schema. Ifissue-investigatoralready wrote the file, append to it; do not overwrite the investigation block. - Size check before implementation. If the 5-line plan does not credibly fit one focused
agent session — the smallest change touches more than one major surface (schema + write path + UI),
the work spans more than one PR, or the validation route is itself multi-day — stop and hand off
to
delivery-planner. The planner writesdestination.mdand a phased plan; come back and execute one phase at a time. If a phase the planner gave you turns out to be too large mid-implementation, do not silently keep going — stop and surface to the user so the planner can re-decompose. - For ambiguous, high-risk, or user-facing changes, get confirmation before proceeding. For clearly specified low-risk changes, continue after stating the plan.
1.5 Reproduce-before-fix gate (bug fixes only)
For any bug fix, regression, or production incident, do not write the fix until you can reproduce the defect deterministically.
- Use
issue-investigatorto confirm root cause and capture a deterministic reproduction recipe in a safe environment (local, sandbox, snapshot, or replayed input — never against live production data). The recipe lives at${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/repro-recipe.ymlper the evidence-pack & repro-recipe schema. - Write the failing regression test FIRST. Commit it as the first commit on the branch
(e.g.,
test: failing test for <TICKET>). The test must fail on the parent commit and pass on the fix commit. The reviewer will verify this by checking out the parent. - If the bug cannot be reproduced or no failing test can be written, escalate via
issue-investigator's Recommended Next Action instead of guessing at a fix. - Skip this gate only for: pure refactors, formatting, docs, or new features without a reported defect — and say so explicitly in the plan.
Phase 2: Implementation
2.1 Code standards
Follow these strictly — see code review checklist for the full list.
Clean code:
- No business logic in controllers or entity classes.
- Methods short, single responsibility. Classes single responsibility.
- Use
Optional(or the language equivalent) for nullable returns; avoid returningnull. - Favor composition over inheritance; do not use inheritance only for code reuse.
- Prefer standard framework solutions before adding third-party libraries for convenience.
- Prefer proper solutions over quick patches — code must make business sense.
Framework / language specifics: see architecture patterns. Key universals:
- Constructor injection over field/setter injection.
- Transactions on service-layer beans only, never on controllers, never on interfaces.
- Entities never directly exposed in the API layer — use DTOs.
- Exception handling via a single global handler, with a typed error response.
- For select-modify-update flows, explicitly check for lost-update risk and choose the right locking strategy. Prefer targeted locking over a blanket isolation level bump.
API design:
- New endpoints documented (OpenAPI/SpringDoc/equivalent) and protected/authorized.
- API responses must not expose sensitive fields (PII, credentials).
- All input validated: request bodies, path variables, headers.
- Pagination, sorting, filtering handled correctly.
- For larger API changes, align on the contract before implementation.
- Avoid in-memory state and non-distributed caches in horizontally scaled services.
- For schedulers or singleton background work, use a locking strategy that works across multiple instances.
Documentation comments:
- Public methods should have doc comments where they clarify intent, parameters, or business rules.
- Skip the obvious (getters/setters, trivial constructors).
Security — see security checklist:
- Role checks restricted to least-privileged roles. No catch-all
permitAll()on wildcard endpoints. - JWT validation: signature, issuer, audience, expiration.
- Keys/passwords in config secrets vaults only — never in source.
- Input validation and output encoding (prevent XSS / injection / SSRF / path traversal).
- Sensitive data must never be logged unmasked at any level. Prefer non-PII identifiers (account id, correlation id).
- Keep
INFOlogging high-value only; downgrade or remove noisy logs that don't help production analysis.
2.2 Migration scripts
- Follow the project's existing migration tooling (Liquibase, Flyway, Alembic, Knex, etc.) and
naming conventions in paths matching
${MIGRATION_PATH_PATTERNS}. - Never modify or reorder existing migration files — always append.
- Include author, meaningful id, and target dbms attribute where the tool supports it.
- Be aware of multi-variant master files (e.g.,
master_<tenant>.xml) and update each variant only when the change applies. - Test migrations against a local database before pushing.
2.3 Resource files
- Excel sheets, XML configs, properties, message catalogs — handle with extreme care.
- Never overwrite or corrupt binary resource files.
- Follow existing patterns for new resource files.
2.4 Inner-loop code review (call code-reviewer)
After the implementation is functional locally and the staged diff is what you intend to commit,
invoke the code-reviewer skill in inner-loop mode. Pass the
compact evidence pack from context discovery so the reviewer sees the project, issue source,
acceptance criteria, and intended behavior without reloading everything from scratch. If expected
behavior or root cause is unclear, use issue-investigator
before treating the review as issue-aware.
- Diff scope: staged changes only (
git diff --staged). - Severities surfaced:
${CODE_REVIEWER_INNER_LOOP_SEVERITIES}(defaultblocker,major). - Blocking behaviour: respect
${CODE_REVIEWER_BLOCKING}— whentrue, do not move to Phase 3 until blocker findings are addressed or explicitly waived with a written justification. - Iteration cap: respect
${CODE_REVIEWER_MAX_ROUNDS}(default3). Round 1 sets the baseline — strict-decrease does not apply on round 1. From round 2 onward each round must produce strictly fewer blocker/major findings than the previous one. If the loop is not converging (Loop: not-convergingorLoop: max-rounds), stop and surface a summary to the user instead of grinding indefinitely. - For bug fixes, reference the failing-test commit from Phase 1.5 in the evidence pack so the reviewer can verify it fails on the parent commit and passes on the fix.
Auto-iterate, do not hand each round back to the user. The engineer owns the inner loop;
the user is the loop's escalation path, not its driver. After each reviewer round, dispatch on
the Loop: signal — continue and needs-context are action signals (do more work, then
re-invoke); converged, not-converging, max-rounds, and needs-user are terminal:
- (terminal, advance)
Loop: converged(noblocker/majorfindings within${CODE_REVIEWER_INNER_LOOP_SEVERITIES}) — proceed to Phase 3. - (action)
Loop: continue— actionable findings remain and either this is round 1 (the baseline) or the round-over-round blocker+major count strictly decreased. Address the findings in code, re-stage (git add -p/git add <files>), and re-invokecode-reviewerin inner-loop mode with--since-last-reviewso the reviewer focuses on the delta. Do this without prompting the user between rounds. The engineer does not mutateevidence-pack.yml.reviewitself —code-reviewerowns that block and snapshots the prior round intoreview.historyand incrementsreview.roundwhen it is re-invoked (seereferences/evidence-pack.md§ Skill responsibilities). - (terminal, escalate)
Loop: not-converging(round N ≥ 2 has the same or more blocker/major findings than round N-1, or the same finding recurs across two rounds), orLoop: max-rounds(${CODE_REVIEWER_MAX_ROUNDS}reached), orLoop: needs-user(a blocker requires a written waiver, scope expansion, or product clarification) — stop the loop and surface to the user: the recurring finding(s), what the engineer tried each round, and the specific decision being asked for (waive / change scope / clarify requirement / stop). Do not advance to Phase 3, do not silently downgrade blockers, do not loop past the cap, and do not invent missing context. - (action)
Loop: needs-context(the reviewer returnedNEEDS_CONTEXT) — invokeissue-investigatororproduct-owner— whichever the reviewer'sFollow-upline points to — and re-invokecode-revieweronce the missing context is captured inevidence-pack.yml. If the named skill itself returnsstatus: needs-context/blocked(the missing context cannot be supplied without the user), this becomes terminal: stop and surface the specific question to the user.
The user only sees inner-loop output when the loop terminates: converged (advance silently to
Phase 3) or one of the four escalation cases (not-converging, max-rounds, needs-user, or
a needs-context that downstream skills cannot resolve). Intermediate continue and resolvable
needs-context rounds stay in the engineer's working context and in
evidence-pack.yml.review.history.
Phase 3: Quality assurance
3.1 Static analysis quality gate
A managed code-quality server (e.g., SonarQube at ${SONAR_HOST_URL}) typically runs in CI/CD. Use
local alternatives to catch issues before pushing:
- SonarLint (recommended) — IDE plugin (VS Code:
SonarSource.sonarlint-vscode, IntelliJ: "SonarQube for IDE"). Standalone mode covers most rules; optional Connected Mode syncs the exact CI ruleset from${SONAR_HOST_URL}when network access exists. - SpotBugs (Java, where configured):
mvn spotbugs:check. - PMD / Checkstyle (Java, where configured):
mvn pmd:check,mvn checkstyle:check. - ESLint / Prettier (JS/TS, where configured):
npm run lint,npm run format:check. - Ruff / Pylint / mypy (Python, where configured).
- Manual walkthrough of the SonarQube checklist.
Quickly verify by category:
- Code smells: unused imports/vars/params, empty catches, commented-out code, magic
numbers/strings, complex methods (cyclomatic > 10), deep nesting, duplicate blocks,
System.out.println/console.logdebugging leftovers, string equality with==, unclosed resources. - Bugs: potential
NullPointerException/undefinedaccess, unchecked casts, mishandled empty collections, legacy date types,equals/hashCodeconsistency. - Vulnerabilities: hardcoded secrets, SQL injection, XSS, path traversal, SSRF, PII in logs.
- Security hotspots:
@CrossOriginscope, weak crypto (MD5/SHA-1 for security), insecureRandom, missing security headers. - Duplication: blocks > ~10 duplicated lines extracted to shared helpers.
3.2 Test coverage
- For user-facing or workflow-heavy changes, use
manual-testerto identify manual validation scenarios and regression risk. - For stable, high-value regression scenarios, use
test-automation-engineerto choose the right automation level and avoid brittle tests. - New code: target
${COVERAGE_TARGET_PERCENT:-80}percent at minimum, 100% for safety-critical code paths. Verify every branch and path you added. (${COVERAGE_TARGET_PERCENT}is an agent-resolved placeholder; the agent reads the value from the loaded.env. When the agent runtime has not loaded.env, treat the target as the literal default80. Resolution order: per-projectcoverage_targetfromPROJECTS_JSONor.agent-skills.yml\u2192COVERAGE_TARGET_PERCENTenv var \u2192 literal80.) - Tests should be fast; slow or noisy tests are a design smell unless there is a real integration reason.
- Service / persistence changes require unit tests. API/interface changes require integration tests plus unit tests for underlying layers.
- Test naming is consistent with the rest of the project. Long test names may use underscores to separate scenario and expectation when that helps readability.
- Use the project's preferred assertion library (AssertJ for Java, Vitest/Jest for TS, pytest for Python). Be consistent.
- Keep test data explicit and deterministic; avoid faker/EasyRandom-style generators unless clearly justified.
- Tests are the source of truth — do not import production constants into tests just to avoid duplication.
- Prefer composition over inheritance in tests; only use abstract base classes for shared annotations/setup when justified.
- If DB cleanup is needed, do it explicitly in teardown rather than wrapping tests in
@Transactionalrollback. - Mock external HTTP services (WireMock / MockServer / msw / responses).
- Use Testcontainers (or equivalent) when an in-memory substitute would not be representative.
- For multi-variant projects, run the relevant variants' test profile.
- Coverage report: open the project's coverage report and verify your changes.
3.3 Build & format
- Run the project's
formatcommand from${PROJECTS_JSON}(typical examples:mvn fmt:format && mvn fmt:check,npm run format,ruff format). Up to three retry passes if a check fails. - Treat formatter configuration as all-or-nothing — do not fight the formatter with personal style tweaks.
- Avoid wildcard imports.
- Pre-flight before running tests: confirm the test setup steps documented in the project /
per-module
README.md(andCONTRIBUTING.mdif present) have been performed — Docker services started, fixture generators run, environment variables exported, generated sources built, required profiles selected. If you skipped Phase 1.2's README pass, do it now before invoking the build command. Do not run tests against a half-configured environment and then report failures; run them against the configuration the README expects. - Run the project's
buildcommand from${PROJECTS_JSON}(typical examples:mvn clean verify,npm test,pytest). All tests must pass. - Diagnose-before-blame rule for failing tests on a clean tree. If tests fail and you
have made no production-code changes (or only changes that cannot plausibly explain the failure),
do not report "tests are broken" or "blocked" yet. First re-read the project / per-module
README.mdandCONTRIBUTING.mdfor required setup, then check.github/workflows/for the exact command CI runs and anyservices:/env:/ setup steps it relies on, then check the test output for missing-prereq signals (connection refused, missing env var, missing fixture, missing generated source, wrong runtime version). Only after that ladder still leaves the failures unexplained is the suite legitimately broken — say so explicitly and cite which documented prerequisite, if any, was unverifiable. - Investigate any new build warnings.
3.4 Dependency security (where configured)
- Run the project's dependency vulnerability scanner if configured (e.g.,
mvn org.owasp:dependency-check-maven:check,npm audit,pip-audit). - Review any new findings introduced by your changes.
3.5 Outer-loop code review (call code-reviewer)
Before moving to Phase 4, invoke the code-reviewer skill in
outer-loop mode:
- Diff scope: full branch diff against the base branch (
git diff origin/<base>...HEAD). - Severities surfaced:
${CODE_REVIEWER_SHOW_SEVERITIES}(defaultblocker,major,minor,nit). - Blocking behaviour: respect
${CODE_REVIEWER_BLOCKING}. - Cross-project impact: include any repo whose name appears in
${SHARED_LIBRARY_NAMES}if it shows up in the diff path.
Pass the same evidence pack plus QA results, commands run, skipped checks, and any waivers from the inner-loop review.
Auto-iterate the outer loop the same way as the inner loop. Apply the four-case rule from Phase 2.4
("Auto-iterate, do not hand each round back to the user") with the outer-loop severity filter
(${CODE_REVIEWER_SHOW_SEVERITIES}, default blocker,major,minor,nit). Address blocker and major
findings in code, fix minor/nit items only when cheap and on-scope, then re-stage, re-run the
targeted parts of QA that the new edits touch (lint/format/affected tests), and re-invoke the
reviewer in outer-loop mode. As in the inner loop, the reviewer (not the engineer) owns
evidence-pack.yml.review — it increments review.round and snapshots the prior round into
review.history when re-invoked.
Only Loop: converged advances to Phase 4. Loop: continue keeps iterating the outer loop;
Loop: needs-context invokes the named skill and re-iterates; Loop: not-converging,
Loop: max-rounds, and Loop: needs-user stop the workflow and surface to the user — Phase 4
must not run with unresolved reviewer findings.
Phase 4: Self-Review
4.1 Self review
- Does the change solve the actual business problem from the ticket?
- Any regression to existing functionality?
- Is the solution proper (not a patch)?
- Edge cases handled?
- Error messages clear and helpful?
- Logging appropriate (not too verbose, not too sparse)?
- If this defect was hard to investigate because evidence was missing, did the fix add the missing log, metric, or correlation id that would make the next occurrence obvious?
- No horizontal-scaling pitfalls (in-memory state, local-only locks, non-distributed caches)?
- No
@SuppressWarnings/// eslint-disable/# noqawithout documented justification? - No
TODO/FIXMEleft without a linked ticket? - All new public methods have doc comments where useful?
- API endpoints documented and protected?
- Migration scripts safe and idempotent?
- If build/run/configuration behavior changed, README/setup docs updated?
- If the service health model changed, health checks and operational logging still make sense?
4.2 Cross-project impact
- If changing anything matching
${SHARED_LIBRARY_NAMES}, document which downstream services are affected. - Flag any breaking API changes.
- Consider backward compatibility.
Phase 5: Commit & PR
5.1 Commit
- Commit message format hint:
${GIT_COMMIT_MSG_FORMAT}— typically<TICKET> <Brief description>. - Stage only relevant files — no IDE configs, no unrelated changes.
- Never bypass git hooks (
--no-verify) without an explicit user-approved waiver recorded in the Definition-of-Done artifact. - For ticket-driven work, the commit set must belong to the single primary Jira key from Phase 1.0. If another independent tracker task was fixed incidentally, split it onto its own branch before continuing.
5.2 Conflict resolution
- If resolving merge conflicts: ensure both your branch and the base branch are up-to-date with remote.
- After conflict resolution, re-run the full build to confirm nothing broke.
5.3 Definition-of-Done artifact
Write
${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/definition-of-done.json
per definition-of-done.md. The reviewer reads this file as
part of its hard-handoff contract and must not declare PASS if any false flag is missing a
written waiver.
- Build, tests, format, lint/static analysis, security scan all
passed: trueor explicitly waived. - For bug fixes:
bug_fix.is_bug_fix: true,regression_test_commitset,fails_on_parent: true,passes_on_head: true,repro_recipe_pathpopulated,observability_addedset honestly. -
git.no_no_verify: trueandgit.branch_starts_with_ticket_key: truefor ticket-driven work. -
git.single_jira_issue_scope: true,git.primary_jira_keyset, andgit.related_jira_keyscontaining context-only linked issues, not independent bundled work. -
git.open_pr_checked_for_existing_work: truewhen Jira is in scope. -
git.pushed_to_remote: trueandgit.pr_urlpopulated before reporting the work as PR-ready. -
scope.shared_library_changedtruthful; iftrue, list affected downstream consumers. -
safety_acknowledgementblock written truthfully. Required whenever the change introduces or performs any mutating action against a deployed environment, or touches credentials / IAM / secrets / backups / monitoring / network policy. Capture the environment, how it was confirmed (a concrete pointer such as a key in${ENVIRONMENTS_JSON}, not a guess from a hostname), the credential used and its source (host-secret-manager/env-var/user-session), the blast radius, the execution path (agent/ci-pipeline/operator-runbook/not-applicable), and explicitno_discovered_credentials_invoked: trueandno_in_repo_tokens_invoked: trueflags. When the change is local-only with no such surface, setsafety_acknowledgement.applies: falsewith a one-line reason and skip the remaining fields. See destructive-action safety policy and the Destructive Action Guardrails section above.
5.4 Pull request
- Push the branch to the remote (
git push -u origin <branch>) before opening or updating the PR. If push is unavailable, final status isneeds-contextorblocked; do not describe the work as ready for review. - PR title follows the same format as the commit.
- PR description explains: what changed, why, and how it was tested.
- Link the tracker ticket, GitHub issue, or supplied issue source in the PR when one exists.
- The PR description must name one primary Jira key. Related keys may appear only in a clearly labelled "Related context" line; they do not expand PR scope.
- Merge strategy:
${GIT_MERGE_STRATEGY}(commonlysquash). - Squash merge commit must start with the ticket key.
- If a checklist item was intentionally overridden, leave a PR comment explaining why.
5.5 Project memory and per-task cleanup
Run this section only after the PR is open (status pr-opened) or the run is reaching a
terminal blocked / abandoned state. Skipping it leaves the workspace cluttered and loses
durable knowledge.
- Update project memory first. For each project touched in this run, append a one-line
bullet under
Recent tasks(<issue-key>: <one-sentence outcome>plus the PR URL when one exists). Append any newly-verified durable fact underBuild & runtimeorCommon gotchas(a non-default Make target, a Testcontainers requirement, a runtime version that surprised the agent, a per-project GitHub account preference confirmed via the GitHub access ladder). Use:python3 scripts/project-memory.py note <project> --section <S> --text <T>. Project memory belongs at${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/_projects/<project-slug>/memory.md. Seedocs/project-memory.mdfor what does and does not belong there. Never write secrets, tokens, customer data, or environment-specific URLs into project memory. - Then clean up per-task scratch. Run
python3 scripts/project-memory.py cleanup-task <issue-key>to delete only${cache_root}/<issue-key>/and everything under it. The script refuses any path starting with_so_projects/is never collateral damage. - Then clean up local branches, but only ones that are safe to drop. A local branch is
safe to delete when it has been merged and pushed (PR closed/merged) or when the run is
abandoned. Rungit branch -d <branch>(never-D); if git refuses because the branch is not merged, leave it. Never delete remote branches, never delete branches forblockedwork, never rungit push --forceto "tidy up". - If the run ends
blockedorneeds-context, skip cleanup entirely — the next agent will need both the per-task scratch and the working branch to resume. Project memory may still be appended (one bullet underRecent tasksdescribing the blocker).
The order — memory first, scratch next, branches last, only when safe — is what guarantees the durable knowledge survives every cleanup pass.
When invoked from a delivery-planner phase
If this run was invoked because a delivery-planner phase named
software-engineer as its recommended_owner:
- Read
destination.mdand the currentphase-NN-<slug>.mdfrom${AGENT_SKILLS_CACHE_DIR:-${WORKSPACE_ROOT:-$REPO_ROOT}/.cache/agent-skills}/<issue-key>/before context discovery. Treat the phase'sInputs,Scope, andValidationas the authoritative brief; do not re-derive scope from the ticket alone. - Open
evidence-pack.ymlfrom the same directory before editing. If it is missing, reconstruct the minimaldelivery_planblock fromphased-plan/README.mdand the phase files, then re-read it. If that cannot be done, stop withBLOCKED: phase continuity evidence-pack missing; do not implement from Markdown files alone. - Confirm
evidence-pack.yml.delivery_plan.phases[<this phase id>].recommended_ownerequalssoftware-engineer. If it does not, stop and surface to the user — running the wrong skill on a phase silently corrupts the plan. - Run the
owner-skill verification recipe
for
software-engineeritself: read<canonical>/software-engineer/SKILL.mddirectly and confirm itsname:field. The host IDE's skill-listing absence is not evidence the file is missing on disk. Record the verified path onphases[<this phase id>].owner_skill_source. - Run the pre-work isolation gate from the
phase-continuity checkpoint,
including the plan-branch gate when
delivery_plan.plan_branchis set. Whenplan_branchis set, check out (do NOT create) that branch (see §1.3). Captureworking_branchfromgit rev-parse --abbrev-ref HEADandbase_branchfrom the matched${PROJECTS_JSON}entry. Ifworking_branch == base_branch, stop withBLOCKED: phase would commit to base branch <name>; do NOT silentlygit checkout -band proceed. - Before material work starts, write
phases[<this phase id>].state: in-progress,working_branch,base_branch,owner_skill_source, andlast_continuity_checkpoint_at, then re-readevidence-pack.ymlto confirm the checkpoint. - If the phase scope clearly exceeds one focused agent session (the size check from
Phase 1.4 fires), write a blocked
phase-continuity checkpoint, record
blocked_reason, recomputecurrent_dispatch_pointer, and stop so the planner can re-decompose on its next run. Do not silently absorb extra scope. - On normal completion (after Phase 5 finishes), write the full
phase-continuity checkpoint:
state: done,completed_at,completed_by: software-engineer,completion_summary,artifacts,validation,follow_up_context,working_branch,base_branch,owner_skill_source, top-levellast_completed_*,last_continuity_checkpoint_at, and the recomputedcurrent_dispatch_pointer. Re-readevidence-pack.ymlafter the write. Without this checkpoint the phase is not complete, even if the code was changed and tests passed. - Regenerate
phased-plan/README.mdfrom the updated evidence pack as part of the same checkpoint write — refresh the phase table'sStatecolumn, thetotals, thelast_completed_*mirrors, thecurrent_dispatch_pointer, and theInputs for the next agentsection, and bumpupdated_at. Do not add, delete, reorder, rename, or resize phases. - Do not invoke
delivery-plannerfrom inside this skill. Phase re-decomposition is the planner's job on its next run, triggered by the user.
Code review hooks
This skill explicitly delegates to code-reviewer at two
points and owns the iteration loop at each one — the user is the loop's escalation path, not
its driver:
- Inner loop: at the end of Phase 2 (Implementation).
- Diff scope: staged diff (
git diff --staged). - Severity filter:
${CODE_REVIEWER_INNER_LOOP_SEVERITIES}. - Purpose: catch major mistakes before testing them.
- Diff scope: staged diff (
- Outer loop: at the end of Phase 3 (QA).
- Diff scope: branch diff (
git diff origin/<base>...HEAD). - Severity filter:
${CODE_REVIEWER_SHOW_SEVERITIES}. - Purpose: issue-aware review of the whole change set.
- Diff scope: branch diff (
Behaviour is configured by ${CODE_REVIEWER_BLOCKING} (default false = advisory). When blocking
is enabled, blocker findings must be addressed or explicitly waived (with a written reason) before
the workflow can advance.
Engineer-owned iteration algorithm (binding for both loops)
Each loop runs the following dispatch on the reviewer's one-line Loop: signal (see
code-reviewer § Final Verdict)
until a terminal signal fires. The six values split into:
- Action signals — engineer does more work, then invokes the reviewer again. Values:
continue,needs-context. - Terminal signals — the loop ends. Values:
converged(advance to next phase),not-converging/max-rounds/needs-user(stop and surface to the user). Aneeds-contextround becomes terminal only if the named follow-up skill itself returnsstatus: needs-context/blocked.
Dispatch:
- (terminal, advance)
Loop: converged→ no findings remain at the loop's severity filter. Exit the loop and advance to the next phase. Do not re-prompt the user. - (action)
Loop: continue→ blocker/major findings remain and either this is round 1 (the baseline — no prior round to compare) or the round-over-round count strictly decreased. Address the findings in code, re-stage, and re-invoke the reviewer with--since-last-review. The reviewer (not the engineer) ownsevidence-pack.yml.review: it snapshots the prior round's counts/verdict intoreview.historyand incrementsreview.roundwhen re-invoked. Do not surface intermediate rounds to the user. - (terminal, escalate)
Loop: not-converging→ round N (N ≥ 2) has the same or more blocker/major findings than round N-1, or the same finding recurs across two rounds. Stop the loop and surface to the user: the recurring finding(s), each round's attempted fix, and the specific decision needed. - (terminal, escalate)
Loop: max-rounds→${CODE_REVIEWER_MAX_ROUNDS}(default3) rounds completed without convergence. Stop and surface as fornot-converging, including the current best diff and a recommendation (waive / change scope / split work / abandon). - (terminal, escalate)
Loop: needs-user→ a blocker requires a written waiver, scope expansion, or product clarification only the user can give. Stop and surface the specific question. - (action)
Loop: needs-context→ reviewer returnedNEEDS_CONTEXT. Invoke the skill the reviewer'sFollow-up:line names (typicallyissue-investigatorfor missing root cause,product-ownerfor missing acceptance criteria), persist the captured context toevidence-pack.yml, and re-invoke the reviewer. If that named skill itself returnsstatus: needs-context/blocked, treat the round as terminal-escalate and surface to the user.
Forbidden in either loop:
- Surfacing the reviewer's per-round output to the user when the signal is an action signal.
- Advancing to the next phase on any signal other than
Loop: converged. - Silently downgrading a
blockerto advisory to make the loop terminate. - Looping past
${CODE_REVIEWER_MAX_ROUNDS}. - Skipping the re-invocation entirely after addressing findings.
- Treating round 1 as
Loop: not-converging; there is no prior round to compare against.
Expected Output Contract
Follow Output Discipline. The shape below is a menu of
available lines, not a checklist. Omit empty sections (here, omit empty lines) — drop
Risks and rollback notes: if there are none, drop Code-reviewer handoff/result: when no
review ran. Required-even-if-empty: the Final status: line.
Always include a lifecycle receipt for code-changing work:
Lifecycle: start-task=<ran|blocked>; task-size=<tiny|small|medium|large>; review=<inner/outer status>; finish-task=<ran|pending|skipped-blocked>; memory=<updated|blocked>; [email protected]. Do not claim a
wrapper, review, memory write, test, or PR action ran unless it actually ran.
## Engineering Result
- Task summary:
- Lifecycle:
- Context reviewed:
- Assumptions and missing context:
- Implementation plan:
- Files/areas likely affected:
- Changes made or proposed:
- Validation performed:
- Tests run:
- Risks and rollback notes:
- Code-reviewer handoff/result:
## Insightful Simplification
<Optional. 1–3 bullets, ≤ 35 words each, anchored to a concrete
file/layer/state/contract/boundary. Omit the section entirely when no
qualifying insight exists. See
[Insightful Simplifications](../../docs/insightful-simplifications.md).>
- ...
## Final Status
- Final status: complete | blocked | needs-context | needs-review
Use proposed rather than made when no files were changed. Do not claim validation, tests,
review, or root-cause confirmation unless that work actually happened.
Output Style (binding)
- Omit empty lines. No
- noneplaceholder bullets just because the template lists the line. - No workflow recap. Do not narrate "I detected mode, then I read the ticket, then ...". Surface the result of each phase that produced one.
- No template echo, no banners. See Output Discipline for the full rule set.
Behavior Checklist
-
start-task.shran before context discovery andfinish-task.shis reflected in the final lifecycle receipt, or the final status explains the blocker. - Required setup, repository identity, base branch, issue source, and validation route are
resolved or the final status is
needs-context/blocked. - Facts, assumptions, missing evidence, and user decisions are separated before editing.
- Bug fixes include investigation, reproducible evidence, and a failing-regression-test strategy unless explicitly out of scope with a stated reason.
- Plan, implementation, validation, and
code-reviewerhandoff all point at the same intended behavior. - Test, build, review, and root-cause claims are backed by commands, outputs, or supplied evidence.
Quality Standards
- Output must distinguish facts, assumptions, missing evidence, and user decisions.
- Implementation plans must be small enough for review and tied to observed code or issue evidence.
- Changes must follow local repository conventions before generic preferences.
- Bug fixes must flow through investigation and a reproducible failing-regression-test strategy unless explicitly out of scope.
- Review results must use the nested
code-reviewercontract and the shared severity/confidence definitions.
Guardrails
- Do not invent missing ticket context, expected behavior, root cause, logs, tests, or standards.
- Do not claim tests were run unless the exact command or manual validation was performed.
- Do not hard-code private company assumptions into this public skill.
- Do not bypass review gates, git hooks, or failing checks without a recorded waiver.
- Do not treat generated output as complete when required evidence is unavailable.
- Do not advance from Phase 2 to Phase 3, or from Phase 3 to Phase 4, when the
code-reviewersignalsLoop: not-converging,Loop: max-rounds, orLoop: needs-user. OnlyLoop: convergedallows the workflow to advance to the next phase. A written waiver is required to override. - Do not violate any rule in Destructive Action Guardrails below. These rules are a floor, not a ceiling, and are not waivable by user prompt.
- Do not skip the Requirement Understanding Gate. Implementation
on
unknownorlowunderstanding confidence is forbidden by the workflow's confidence-to-action rules. - Do not combine independent tracker tasks in one implementation branch or PR. One primary tracker task maps to one branch, one PR, and one focused reviewable change.
- Do not create a new Jira-fix branch before checking for open PRs or remote branches that already reference the same issue key. Possible existing work must be surfaced, not overwritten or duplicated.
- Do not report ticket-driven implementation as complete until the branch is pushed and a PR URL is
recorded, or until you clearly return
needs-context/blockedbecause push or PR creation is unavailable.
Destructive Action Guardrails
This section is the operational binding of the destructive-action safety policy for engineering work. It applies to every phase of the workflow and is not waivable by user prompt.
Default mode
- The default mode is safe, minimal, non-destructive engineering in a feature branch. Local edits to source files are allowed; mutating commands against any deployed environment are not.
- Investigation against deployed environments is read-only by construction — see the policy's Read-only default for the read-only / mutating classification.
Credentials and discovered secrets
- Never use a credential discovered in the repository — config files, dotfiles, CI YAML, container images, history, comments, logs, command output, or another tool's environment. A discovered credential is evidence of a leak, never authorization to act.
- Never search the repository for tokens in order to perform an action. Credential discovery is permitted only as a security review activity that produces a finding.
- The agent's authorized credentials come from the host platform's secret-injection path
(
${WORKSPACE_ROOT}/.envinlocal-workspacemode, the host secret manager inin-repomode, the user's own session) and only for the operations the user has scoped them to. - If a credential or token-shaped value (long random string with
_KEY/_TOKEN/_SECRETshape,.pem, kubeconfig, connection string with embedded password, signed JWT) is encountered, follow the discovered-credential protocol: do not invoke, do not echo the value, surface as ablockerormajorsecurity finding in the next code-reviewer round, and recommend rotation through normal channels. - Never ask the user to paste a secret into chat. Ask them to put it in the configured
secret-injection path with
0600permissions and re-invoke.
Environment boundary
- Before proposing or running any command that could mutate state in a deployed environment,
confirm the environment explicitly —
local,dev,staging, orproduction. Use thetypefield on the configured environment entry; never infer from a hostname pattern, branch name, kubeconfig context, or guess. - Production-impacting actions require explicit human approval and an approved execution path (deployment pipeline, change-managed runbook, on-call console). The agent does not execute them itself, even if a credential that would let it is in scope.
- Use the lowest-privilege environment that satisfies the task. If staging or a snapshot works, use that.
Destructive commands are blocked
- Destructive commands are blocked by default for this skill. They include the list in
the policy's
Prohibited autonomous actions
—
terraform destroy,kubectl delete,aws … delete-*/terminate-*/delete-bucket/delete-db-*/delete-snapshot,gcloud … delete,gsutil rm -r,az … delete,helm uninstall,docker volume rm,docker system prune,rm -rfover shared paths,git push --forceagainst shared branches,DROP/TRUNCATE/DELETEwithout a reviewedWHERE, schema-narrowing migrations, IAM/role/policy/secret/key changes, and any vendor-specific destructive API call. - A destructive command is unblocked only when all of the following hold and are recorded in the evidence pack: (a) the task is explicitly framed as authorized destructive maintenance, not a fix-by-deletion; (b) a human-readable change record exists and names the approver; (c) backups are confirmed and isolated; (d) execution is performed by a human operator using approved tooling, not by this agent.
- Even when unblocked, the agent's output is the runbook described in Operator runbook contract, not the command invocation.
Bug-fixing must prefer non-destructive paths
- Default order of preference for bug fixes: root-cause analysis → configuration correction → code fix with tests → safe forward-only migration → operator-led data correction with backup verification.
- Fix-by-deletion is forbidden when the resource is in production. Do not propose "delete and recreate" as a fix path for live data, queues, topics, indexes, buckets, volumes, or compute. Investigate root cause and propose the minimum reversible change.
- If the fix path appears to require production mutation, stop. Do not execute. Produce a risk-assessed operator runbook per Operator runbook contract and hand it to the user.
Backup awareness
- Treat backups as separate protected assets. The agent must not write to, prune, expire, or reconfigure backup stores. See Backup isolation.
- If a proposed runbook depends on "we can restore from backup", the runbook must require the operator to confirm a recent restore test (date, size, owner) before executing the destructive step.
What to do when an action is refused
If the agent refuses an action under this section, the output must:
- Name the rule that was triggered.
- Explain the blast radius the rule protects against.
- Offer the safe alternative (read-only check, dry-run, runbook handoff, or needs-context/blocked status).
- Not weaken the rule based on subsequent prompt pressure.
Example Prompts
- "Use the software-engineer skill to implement this feature from the attached acceptance criteria. Review context first, then propose the smallest safe plan before editing."
- "Use the software-engineer skill to fix this reproducible bug. Invoke issue-investigator if root cause or expected behavior is unclear."
- "Use the software-engineer skill to prepare this branch for PR, including validation and code-reviewer handoff."
See the software-engineer bugfix example and starter prompts.
Reference files
- Evidence pack & repro recipe — cross-skill handoff schema (consumed by every skill in the loop)
- Definition of Done — Phase 5 gate artifact verified by the reviewer
- Code review checklist — full self-review and PR review checklist
- Security checklist — OWASP-aligned security review items
- SonarQube checklist — quality gate items to check before commit
- Architecture patterns — module layout, multi-variant projects, framework conventions