Skip to main content

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-plan explains branch routing before work starts.
  • feature-report combines branch policy, pull-request evidence, checks, review state, base freshness, and conflicts.
  • feature-finalization separates 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.