Publication Workflows
DevNexus starts with a simple publication posture. A normal workspace can use work items, isolated worktrees, focused verification, and review handoff without configuring versions, release trains, or CI budgets.
For the higher-level branch strategy and pause/resume model around Git workflows, see Git workflow integration.
Use the advanced publication tools only when the workspace needs them. A team can opt into green-main checks, CI tiers, candidate branches, merge queues, remote runners, or version-scoped release trains later.
Simple Default
The default publication strategy is review_handoff. In that mode an agent can
prepare a branch, record verification, and leave the user or maintainer with a
clear handoff. DevNexus does not require hosted CI, target-branch pushes,
version planning, or release trains.
This is the right starting point for most users:
- first workspaces
- small teams
- repositories without branch protection
- one-off fixes
- local or manual review workflows
You can omit publication policy entirely and use the default. If you want the default to be explicit, configure the component like this:
{
"components": [
{
"id": "api",
"name": "API",
"kind": "git",
"role": "primary",
"remoteUrl": "git@github.com:ExampleOrg/api.git",
"defaultBranch": "main",
"sourceRoot": "../api",
"publication": {
"strategy": "review_handoff"
}
}
]
}
A typical agent flow stays short:
dev-nexus worktree prepare <workspace-root> --component api --work-item local-1
dev-nexus work-item comment <workspace-root> local-1 --component api --body "Prepared a branch and ran focused verification."
The user or maintainer decides whether to push, open a pull request, merge, or ask for more work.
When publication should be authored as a human account but credit one or more agent participants, configure the primary Git identity and every co-author trailer explicitly:
{
"automation": {
"publication": {
"strategy": "review_handoff",
"remote": "origin",
"actor": {
"kind": "human",
"provider": "github",
"handle": "alice"
},
"gitIdentity": {
"name": "Alice",
"email": "123456+alice@users.noreply.github.com",
"coAuthors": [
{
"name": "Codex",
"email": "267193182+codex@users.noreply.github.com"
},
{
"name": "Pair Reviewer",
"email": "pair-reviewer@example.invalid"
}
]
}
}
}
}
DevNexus prepares the worktree with the configured primary user.name and
user.email. It also renders all configured Co-authored-by trailers in the
worker briefing so the commit message can credit every configured co-author.
GitHub and GitLab both use this trailer format for co-author attribution; GitLab
also exposes the same trailer text through merge-request commit templates.
DevNexus treats review and publication as separate concepts. Review decides how a change is checked and approved; publication decides whether it may be pushed, merged, queued, or released. The target review-policy design is recorded in Review policy design.
When a component configures review policy, agents can ask DevNexus for the current review path:
dev-nexus review plan <workspace-root> --component api --path docs/guide.md
The review plan is read-only by default. It reports the transport, gates, required evidence, provider mutations, blocked actions, and next action. Local human approval is action-scoped: if the branch, head commit, or requested action changes, the review plan should ask for fresh authorization.
DevNexus does not store local approval ledgers in the workspace repository. Provider reviews are the durable record when the review happens in a pull request or merge request. Local authorization is current-action input; teams that need audit-grade local approvals should use a future opt-in backend ledger, not source-controlled JSON.
Publication commands enforce configured component review policy only at final actions. Opening or updating a pull request remains allowed because it creates the review surface. Pull-request merge and direct target-branch push are blocked until the review plan is ready.
When To Opt Into Advanced Publication
Use a richer publication policy when local handoff is no longer enough.
Choose green_main when the workspace has protected branches, required checks,
or a bot account that should open pull requests and wait for CI before merge.
Choose CI tiers when every change should not run the same hosted matrix. CI tiers let the workspace distinguish local focused checks, cheap remote smoke, candidate matrix checks, protected target gates, and scheduled drift checks.
Choose a release train when you want to batch several work items into an integration or candidate branch before final publication. Version planning can name the scope, but it remains optional. A workspace can use unscoped candidate planning or no train at all.
Advanced Opt-In Example
This example opts into a green-main workflow and a version-scoped release train. It is suitable for a workspace that wants ordinary pull requests to run cheap remote smoke first, then run the full matrix for candidate validation and for every pull request whose base branch is the protected target branch.
{
"versionPlanning": {
"versions": [
{
"id": "v-next",
"objective": "Batch the next user-facing release.",
"owningComponents": [
"api"
],
"targetBranch": "main",
"scope": [],
"readinessGates": [
{
"kind": "work_items_done",
"components": [
"api"
]
},
{
"kind": "checks_green",
"components": [
"api"
],
"checkNames": [
"Node 22 check"
]
}
],
"releasePolicy": {
"tags": "none",
"packages": "none",
"providerRelease": "none"
}
}
]
},
"automation": {
"verification": {
"ciTiers": {
"defaultTier": "remote_smoke",
"fullMatrixBudget": {
"minimumIntervalMinutes": 60,
"minimumChangeCount": 3
}
}
},
"publication": {
"strategy": "green_main",
"remote": "bot",
"targetBranch": "main",
"push": false,
"greenMain": {
"integrationPreference": "pull_request",
"directTargetPush": "blocked",
"mergeAuthority": "authorized_merge",
"requiredChecks": [
"Node 22 check (ubuntu-latest)",
"Node 22 check (windows-latest)",
"Node 22 check (macos-latest)"
],
"staleChecks": "block"
},
"releaseTrain": {
"enabled": true,
"activeVersionId": "v-next",
"branchNaming": {
"integrationPrefix": "integration",
"candidatePrefix": "candidate",
"unscopedName": "manual"
},
"selector": {
"statuses": [
"ready"
],
"labels": []
}
}
}
}
}
The labels array is empty on purpose. Public repository users should not need
an internal label to use release trains. Add labels only when the component
owner wants an explicit queue filter.
Feature Branch Delivery
Use feature branch delivery when a single objective needs several reviewable
changes but should still have one coherent final publication path. A feature is
the planning object. Branch names still use normal Git intent prefixes such as
feat/, fix/, chore/, docs/, refactor/, test/, or ci/.
The default long-running feature shape is hybrid:
- one approved feature branch, such as
feat/codex-goals; - review branches that target that feature branch, such as
feat/codex-goals/target-projection; - optional stacked review branches when one change depends on another;
- one final pull request from the feature branch to the target branch;
- human approval for the branch strategy choice and final publication.
Prefer configuring long-running branch policy under
automation.gitWorkflows.profiles. Older
automation.publication.releaseTrain.featureBranchDelivery config remains
readable and is projected as the legacy-feature-branch-delivery Git workflow
profile when automation.gitWorkflows is omitted. Keep release trains focused on
batching, candidate branches, CI tiers, and final publication.
A modern feature workflow profile looks like this:
{
"automation": {
"gitWorkflows": {
"activeProfileId": "codex-goals",
"profiles": [
{
"id": "codex-goals",
"branchStrategy": "hybrid",
"targetBranch": "main",
"activeFeatureId": "codex-goals",
"allowedBranchStrategies": ["direct", "stacked", "feature_branch", "hybrid"],
"branchNaming": {
"defaultIntentPrefix": "feat",
"allowedIntentPrefixes": ["feat", "fix", "chore", "docs"],
"featureBranchPattern": "{intent}/{feature}",
"reviewBranchPattern": "{intent}/{feature}/{change}"
},
"review": {
"mode": "review_branch_pr",
"finalPullRequest": true,
"finalPullRequestCreation": "at_review_gate"
},
"branchPublication": {
"strategy": "push_remote_then_fallback",
"fallbackRemote": "fork"
}
}
]
}
}
}
The legacy release-train form is still accepted during migration:
{
"automation": {
"publication": {
"strategy": "green_main",
"targetBranch": "main",
"releaseTrain": {
"enabled": true,
"activeVersionId": "v-next",
"branchNaming": {
"integrationPrefix": "integration",
"candidatePrefix": "candidate",
"unscopedName": "manual"
},
"featureBranchDelivery": {
"enabled": true,
"activeFeatureId": "codex-goals",
"defaultBranchStrategy": "hybrid",
"allowedBranchStrategies": ["direct", "stacked", "feature_branch", "hybrid"],
"branchNaming": {
"defaultIntentPrefix": "feat",
"allowedIntentPrefixes": [
"feat",
"fix",
"chore",
"docs",
"refactor",
"test",
"ci"
],
"featureBranchPattern": "{intent}/{feature}",
"reviewBranchPattern": "{intent}/{feature}/{change}"
},
"review": {
"mode": "review_branch_pr",
"finalPullRequest": true,
"finalPullRequestCreation": "at_review_gate"
},
"provider": {
"commentPolicy": "status_only"
},
"branchPublication": {
"strategy": "push_remote_then_fallback",
"fallbackRemote": "fork"
}
},
"selector": {
"statuses": ["ready"],
"labels": []
}
}
}
}
}
Feature branch delivery uses three read-only commands:
feature-planexplains branch routing before work starts.feature-reportcombines branch policy, pull-request evidence, checks, review state, base freshness, and conflicts.feature-finalizationseparates review readiness from publication authority. A draft pull request can be safe to review while still blocked for final publication. When component review policy is configured, each item also carries the resolved review plan for the final pull request. A green, approved pull request still stops at the human publication gate unless policy explicitly grants more authority.
For stacked and hybrid branch strategies, the plan also carries a stack summary:
publication eligibility, root branch, default parent branch, review target, and
any known change entries. Worker context records the selected review-branch
parent and stack position when the change worktree is prepared. DevNexus also
exposes a provider-neutral restack plan model for branch graph facts; it reports which
branches need update, which pushed branches require --force-with-lease, and
which updates need human approval.
finalPullRequestCreation controls when the final feature pull request is
opened. The default, at_review_gate, avoids creating a long-lived PR while the
feature branch is still accumulating commits. Use at_feature_start only
when the team accepts repeated PR CI on every branch update, and manual_only
when DevNexus should report readiness without recommending provider mutation.
branchPublication controls where feature and review branches are expected to
be pushed. push_remote uses the component push remote.
push_remote_then_fallback records a configured fallback remote, such as
a fork, for machines or actors that cannot push to the upstream repository.
fallback_remote always targets the fallback. manual_only reports the branch
shape without selecting a push remote.
When the selected fallback remote is a GitHub fork, DevNexus resolves the remote
URL and renders the final pull-request head as owner:branch. If the fallback
remote is missing or does not point at a GitHub repository, finalization blocks
with a setup action instead of guessing. branch-push --feature probes
push_remote_then_fallback with read-only git push --dry-run calls and uses
the fallback only when the push remote rejects the dry run.
When provider evidence says the feature review branch is behind or diverged,
feature-report and feature-finalization include a branch update
decision. The default recommendation is a merge update into the review branch:
it refreshes CI without rewriting public history. Rebase remains an explicit
alternative for teams that want a linear branch, but it requires human approval
and a --force-with-lease push. Leaving the branch unchanged keeps the risk that
CI passes against stale base code and fails after merge.
For GitHub, keep routine provider output quiet. Prefer PR bodies, checks, labels, and DevNexus reports for ordinary state. Comments should be reserved for major redirection, explicit human request, or a provider that has no quieter durable field.
Advanced Commands
The publication commands produce planning and evidence output. They do not make a workspace advanced by themselves; they are useful after the workspace config opts into the matching policy.
Inspect green-main checks from saved provider facts:
dev-nexus publication green-main plan <workspace-root> --component api --pr <pr-number> --checks-file checks.json
Normalize saved provider evidence:
dev-nexus publication evidence normalize evidence.json
Collect pull-request evidence through the configured publication credential:
dev-nexus publication pull-request evidence <workspace-root> --component api --number 123 --json
Prepare a provider review through the configured publication credential:
dev-nexus publication pull-request upsert <workspace-root> --component api --head feat/example --title "Add example" --dry-run --json
dev-nexus publication review-handoff <workspace-root> --component api --branch feat/example --title "Add example" --json
pull-request upsert --dry-run resolves the repository, base/head branch,
credential profile, actor, and create/update plan without contacting the forge.
review-handoff composes the configured branch push and pull-request upsert so
agents do not choose remotes or accounts manually. If the local branch tracks a
different remote than the component publication policy, the branch push result
reports that mismatch in its warnings.
Review merge queue readiness:
dev-nexus publication merge-queue-readiness <workspace-root> --component api
Review release train readiness:
dev-nexus publication release-train-readiness <workspace-root> --version v-next
Plan candidate branches:
dev-nexus publication candidate-plan <workspace-root> --version v-next
Review feature branch routing:
dev-nexus publication feature-plan <workspace-root> --component api
Review feature branch provider state from saved evidence:
dev-nexus publication feature-report <workspace-root> --component api --evidence-file evidence.json
The report is read-only. It classifies the feature review branch as needing final pull-request creation, provider evidence, branch update, conflict resolution, branch-policy resolution, check follow-up, review, or final publication readiness. Saved provider evidence can include pull-request review state and base freshness, so an out-of-date but otherwise mergeable GitHub pull request is flagged before publication.
Review finalization readiness before undrafting, requesting review, or merging:
dev-nexus publication feature-finalization <workspace-root> --component api --evidence-file evidence.json
The finalization plan is also read-only. It reports whether the branch is safe for review, whether configured review gates are satisfied, whether it is ready for publication, and whether publication still requires a human decision. It does not merge, undraft, comment, or enter a merge queue.
When a final action needs local human authorization, pass the current instruction to the mutating command:
dev-nexus publication pull-request merge <workspace-root> --component api --number 123 --authorized --authorization-summary "Approved in local review"
Choosing A Path
Start with review_handoff unless the workspace already has a reason to do
more. Add green_main when protected-branch publication needs machine-readable
check decisions. Add CI tiers when hosted CI cost or platform coverage needs
policy. Add release trains when the team wants to batch related work before
final publication. Add feature branch delivery when several changes should
share one durable branch, one review branch, and one final publication gate.
Self-hosting workspaces can use the advanced path to reduce CI noise and protect shared branches. That is an opt-in operating profile, not the DevNexus default.