@acrasie/dev-flow 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.codex-plugin/plugin.json +20 -0
  2. package/LICENSE +21 -0
  3. package/README.md +181 -2
  4. package/dist/codex-dev-flow.mjs +3 -0
  5. package/dist/dev-flow.mjs +241 -0
  6. package/docs/adr/0001-hybrid-portable-workflow.md +23 -0
  7. package/docs/adr/0002-share-an-invalidable-context-capsule.md +55 -0
  8. package/docs/adr/0004-scale-assurance-lanes-by-applicable-risk.md +36 -0
  9. package/docs/adr/0006-make-intake-adaptive-user-authoritative-and-token-efficient.md +76 -0
  10. package/docs/adr/0007-collect-opt-in-local-benchmark-feedback.md +82 -0
  11. package/docs/adr/0008-automate-maintainer-releases-with-an-interactive-bun-workflow.md +121 -0
  12. package/docs/adr/0009-separate-intake-decisions-from-shape-discovery.md +200 -0
  13. package/docs/adr/0010-choose-quick-or-plan-after-discovery.md +161 -0
  14. package/docs/adr/0011-separate-fast-local-and-authoritative-ci-quality-gates.md +49 -0
  15. package/docs/adr/0012-use-bun-test-and-require-node-24.md +41 -0
  16. package/docs/adr/0013-layer-source-distribution-and-runtime-tests.md +42 -0
  17. package/docs/adr/0014-ratchet-source-coverage-with-bun.md +51 -0
  18. package/docs/adr/0015-split-fast-and-type-aware-linting.md +41 -0
  19. package/docs/adr/0016-use-husky-with-a-tested-bun-staged-file-adapter.md +45 -0
  20. package/docs/adr/0017-format-conservatively-with-oxfmt.md +45 -0
  21. package/docs/adr/0018-use-a-high-signal-oxlint-policy.md +53 -0
  22. package/docs/adr/0019-gate-deterministic-size-and-observe-timing.md +44 -0
  23. package/docs/adr/0020-support-linux-and-macos-with-targeted-ci.md +41 -0
  24. package/docs/adr/0021-randomize-tests-without-retries.md +35 -0
  25. package/docs/adr/0022-use-one-root-bun-workspace.md +41 -0
  26. package/docs/adr/0024-make-gate-a-minimal-plan-approval.md +74 -0
  27. package/docs/adr/0025-end-the-lifecycle-after-assure.md +55 -0
  28. package/docs/adr/0026-keep-intake-product-stable-and-interview-shape-by-dependency.md +151 -0
  29. package/docs/adr/0027-add-agentic-project-init-and-versioned-engineering-profiles.md +147 -0
  30. package/docs/adr/0028-make-public-documentation-user-first-and-current.md +65 -0
  31. package/docs/adr/0029-make-build-a-native-execution-boundary.md +51 -0
  32. package/docs/adr/0030-unify-product-domain-and-technical-design-interviews.md +240 -0
  33. package/docs/adr/0031-make-assure-the-success-boundary.md +205 -0
  34. package/docs/artifacts.md +47 -0
  35. package/docs/baselines/2026-07-18-p0-lifecycle.json +142 -0
  36. package/docs/design.md +101 -0
  37. package/docs/getting-started.md +204 -0
  38. package/docs/glossary/dev-flow.md +527 -0
  39. package/docs/lifecycle-contract.md +189 -0
  40. package/docs/lifecycle-contract.projection.json +931 -0
  41. package/docs/metrics-protocol.md +113 -0
  42. package/docs/project-profile-contract.md +157 -0
  43. package/docs/runbooks/maintainer-release.md +291 -0
  44. package/docs/target-intake-shape-contract.md +416 -0
  45. package/package.json +68 -4
  46. package/schemas/config.schema.json +104 -0
  47. package/schemas/policy.schema.json +17 -0
  48. package/schemas/project-init-state.schema.json +159 -0
  49. package/schemas/project-profile-local.schema.json +53 -0
  50. package/schemas/project-profile.schema.json +285 -0
  51. package/schemas/state.schema.json +826 -0
  52. package/skills/debug-root-cause/SKILL.md +16 -0
  53. package/skills/design-decisions/SKILL.md +24 -0
  54. package/skills/dev-flow/SKILL.md +306 -0
  55. package/skills/dev-flow/agents/openai.yaml +6 -0
  56. package/skills/discover-change/SKILL.md +31 -0
  57. package/skills/plan-change/SKILL.md +29 -0
  58. package/skills/review-change/SKILL.md +21 -0
@@ -0,0 +1,113 @@
1
+ # Lifecycle measurement protocol
2
+
3
+ ## Status and purpose
4
+
5
+ This protocol is normative from `P8.1`. It measures quota/token cost and lifecycle
6
+ reliability without changing transition eligibility. Reliability and truthful status
7
+ remain hard gates; measurements can never authorize success.
8
+
9
+ ## Privacy boundary
10
+
11
+ Metric events use an allowlist. They may contain only:
12
+
13
+ - schema version and monotonically increasing sequence/timestamp numbers;
14
+ - opaque per-run UUID generated independently from task/objective identity;
15
+ - preparation profile (`quick|plan|unselected`), macro-phase, metric, numeric value,
16
+ measurement label, and source enum.
17
+
18
+ Never accept or store raw task ID, prompt, objective prose, source code, diff, file content, secret, credential,
19
+ raw command output, model response, exception message, user identity, remote URL, or
20
+ artifact prose. Unknown event fields fail closed rather than being copied or redacted
21
+ afterward.
22
+
23
+ ## Measurement truthfulness
24
+
25
+ Every numeric observation is one of:
26
+
27
+ - `measured`: native counter or deterministic local observation;
28
+ - `estimated`: explicit estimate/proxy, never displayed as native usage;
29
+ - `unavailable`: field absent from events and explicit in reports.
30
+
31
+ Allowed source bindings:
32
+
33
+ | Metric | Measurement | Source |
34
+ | ------------------------------------------------------------------------------------ | ----------- | ------------------------- |
35
+ | `input_tokens`, `output_tokens` | `measured` | `native_token_api` |
36
+ | `input_tokens`, `output_tokens` | `estimated` | `explicit_token_estimate` |
37
+ | `token_proxy_context_bytes` | `estimated` | `context_bytes_proxy` |
38
+ | `latency_ms` | `measured` | `monotonic_clock` |
39
+ | `false_success_detections` | `measured` | `operator_audit` |
40
+ | structural lifecycle counters | `measured` | `state_history` |
41
+ | model/delegation/context/capsule counters | `measured` | `orchestrator_counter` |
42
+ | INTAKE questions/avoided/recommendation/zero-path/reopen counters | `measured` | `orchestrator_counter` |
43
+ | SHAPE Discovery/Planning session, targeted invalidation, and evidence reuse counters | `measured` | `orchestrator_counter` |
44
+ | GATE preflight and approval-reuse counters | `measured` | `orchestrator_counter` |
45
+ | GATE decision and targeted-return counters | `measured` | `state_history` |
46
+
47
+ Missing token or latency telemetry is `unavailable`, never numeric zero. Estimated data
48
+ cannot be combined with measured data without retaining both labels and sources.
49
+ Contract fixtures may source false-success detection only from `contract_tests`; runtime
50
+ traces require `operator_audit`.
51
+
52
+ ## Event and aggregation contract
53
+
54
+ `createLifecycleMetricEvent()` enforces event fields, enums, non-negative values,
55
+ measurement/source compatibility, and allowlisted model/effort/quota-pressure dimensions
56
+ for model calls. `summarizeLifecycleTrace()` validates every edge
57
+ against canonical `STATE_MACHINE` before counting transitions, gates, blocks, resumes,
58
+ ASSURE checks, evidence reuse, review calls/escalations, and correction cycles.
59
+
60
+ Runtime collection must call non-throwing `tryCreateLifecycleMetricEvent()`. Rejected
61
+ telemetry returns only `metric_rejected`; it never changes workflow state or exit status.
62
+ Strict constructors remain for tests/offline validation. Latency summaries accept only an
63
+ explicit `{measurement: measured, source: monotonic_clock}` observation; other data stays
64
+ `unavailable`.
65
+
66
+ Aggregation groups by contract version, preparation profile, macro-phase, metric, measurement, and
67
+ source. Median/p90 require runtime samples; contract fixtures report structural counts
68
+ only. False-success target remains absolute zero. A detected false success invalidates
69
+ optimization acceptance regardless of token or latency improvement.
70
+
71
+ Instrumentation is observational and removable: disabling event collection must not
72
+ change state, guards, approvals, assurance, or exit status.
73
+
74
+ ## P0 baseline
75
+
76
+ [`baselines/2026-07-18-p0-lifecycle.json`](baselines/2026-07-18-p0-lifecycle.json) is a
77
+ reproducible contract-fixture baseline generated by `npm run baseline:p0`. It covers one
78
+ canonical Quick and Plan trace under TaskState V6. Both cross all five phases.
79
+
80
+ Limitations are explicit:
81
+
82
+ - `contract_fixture_not_runtime`;
83
+ - `token_telemetry_unavailable`;
84
+ - `latency_telemetry_unavailable`.
85
+
86
+ This is structural baseline, not dogfooding performance claim. Runtime median/p90 remain
87
+ pending until P1+ supplies durable orchestration events.
88
+
89
+ ## Mandatory before/after record for P1–P7
90
+
91
+ Every approved change artifact in P1, P2, P3, P4, P5, P6, and P7 must contain compact
92
+ measurement projection:
93
+
94
+ ```yaml
95
+ measurement:
96
+ schemaVersion: 1
97
+ baselineRef: plugins/codex-dev-flow/docs/baselines/2026-07-18-p0-lifecycle.json
98
+ budget:
99
+ falseSuccessMax: 0
100
+ requiredEvidenceRegressionMax: 0
101
+ targetMetrics: []
102
+ after:
103
+ sampleRefs: []
104
+ unavailableMetrics: []
105
+ delta:
106
+ measured: []
107
+ estimated: []
108
+ reliabilityGate: pending
109
+ ```
110
+
111
+ `after` and `delta` stay pending before implementation evidence exists. A missing metric
112
+ is recorded under `unavailableMetrics`; it is never inferred as improvement. Comparison
113
+ must use matching preparation-profile/source/measurement and preserve raw evidence outside metric data.
@@ -0,0 +1,157 @@
1
+ # Project Engineering Profile Contract
2
+
3
+ This document is normative for agentic `$dev-flow init`, shared project profiles, local
4
+ overlays, validation, reconciliation, and publication. It is outside TaskState lifecycle
5
+ and does not yet make project profiles part of ordinary SHAPE completion.
6
+
7
+ ## Interfaces
8
+
9
+ - `$dev-flow init`: agentic Discovery, adaptive interview, validation, and explicit
10
+ Profile Approval.
11
+ - `npx @acrasie/dev-flow init`: separate deterministic plugin-configuration wizard.
12
+ - `dev-flow project-profile inspect`: read existing shared/local profiles and
13
+ ignore status.
14
+ - `dev-flow project-profile validate [--local]`: validate stdin without writing.
15
+ - `dev-flow project-profile publish [--local]`: publish validated stdin after
16
+ agent confirms explicit Profile Approval.
17
+ - `dev-flow project-profile view [--local]`: render exact published canonical
18
+ YAML.
19
+ - `dev-flow project-profile session-view|session-save|session-clear`: resume,
20
+ persist, or remove compact local INIT interview state.
21
+
22
+ `project-profile` commands are deterministic backend primitives. They perform no model
23
+ call, repository discovery, interview, or approval inference.
24
+
25
+ ## Agentic INIT
26
+
27
+ INIT discovers repository facts before asking. Core scope is stack, source structure,
28
+ architecture boundaries, dependency direction, naming, error handling, testing, and
29
+ quality. Frontend, API, data, security, concurrency, performance, compatibility,
30
+ migration, observability, deployment, rollback, and operations activate only when
31
+ applicable.
32
+
33
+ Questions are limited to missing, contradictory, stale, or material decisions and
34
+ appear exactly one at a time. Each carries evidence, recommendation and confidence,
35
+ 2–3 viable options, direct consequences, and free-form path. There is no hard question
36
+ cap, periodic progress checkpoint, or cost-estimation prompt. Greenfield INIT produces
37
+ profile and optional generated diagram only, never product scaffold.
38
+
39
+ Compact local `.codex/project-init/state.yaml` persists normalized decisions, stale
40
+ keys, status, candidate digest, and at most one exact active question. Schema:
41
+ [project-init-state.schema.json](../schemas/project-init-state.schema.json). It contains
42
+ no transcript or hidden reasoning and is gitignored. Every save preserves session/profile
43
+ identity and increments revision exactly once. Resume reuses active question unless
44
+ dependency evidence changed. Successful publication clears session explicitly.
45
+
46
+ Multi-service Discovery is progressive. Each repository owns its profile. Root profile
47
+ contains logical topology, responsibilities, dependencies, contracts, and external
48
+ profile refs. Absolute service paths stay local. An inaccessible service claim is
49
+ `user_asserted`, never verified evidence. External repository update requires own
50
+ validation and approval transaction.
51
+
52
+ ## Shared profile
53
+
54
+ Canonical shared file is versioned:
55
+
56
+ ```text
57
+ .codex/dev-flow.project.yaml
58
+ ```
59
+
60
+ Schema: [project-profile.schema.json](../schemas/project-profile.schema.json).
61
+
62
+ Required content:
63
+
64
+ - stable project identity and stack;
65
+ - logical service topology and contracts;
66
+ - all eight core convention categories plus applicable optional categories;
67
+ - decision rationale, provenance, durable fingerprints, and dependency edges;
68
+ - optional `domainDocumentation` conventions: single/multiple context mode, portable
69
+ glossary/rules/ADR/context-map paths, language, stable identity/link conventions, and
70
+ source fingerprints;
71
+ - optional relative Markdown diagram refs below `.codex/dev-flow/diagrams/`; and
72
+ - monotonic revision, canonical content digest, and Profile Approval Receipt.
73
+
74
+ Decision dependency graph is acyclic. `user_asserted` decisions cannot carry verified
75
+ fingerprints. Shared profile rejects secret-like values, local absolute filesystem
76
+ paths, duplicate identities, unknown service/dependency refs, and missing core domains.
77
+ Volatile task observations never belong here.
78
+
79
+ Canonical content digest is SHA-256 of recursively key-sorted JSON representation of
80
+ `content`. Receipt remains outside content digest to avoid cycle. Receipt binds actor
81
+ `user`, approval time, profile identity, revision, and exact content digest; receipt
82
+ digest binds those fields. Any mismatch makes profile invalid.
83
+
84
+ ## Local overlay
85
+
86
+ Local file is gitignored:
87
+
88
+ ```text
89
+ .codex/dev-flow.project.local.yaml
90
+ ```
91
+
92
+ Schema: [project-profile-local.schema.json](../schemas/project-profile-local.schema.json).
93
+ Before publication repository `.gitignore` must contain exact path entry. Overlay may
94
+ contain only absolute local service paths and non-contractual preferences. Service IDs
95
+ must exist in shared topology when shared profile exists. A preference cannot override
96
+ shared decision key. Local profile identity and optional shared digest binding must
97
+ match shared profile.
98
+
99
+ ## Authority
100
+
101
+ ```text
102
+ system instructions and repository policy
103
+ -> INTAKE product decisions when task-scoped
104
+ -> explicitly approved task exception
105
+ -> shared engineering profile
106
+ -> non-contractual local preferences
107
+ -> agent defaults
108
+ ```
109
+
110
+ Lower authority cannot weaken higher authority. Domain destination resolution uses
111
+ repository policy, approved profile, unambiguous detected convention, then portable
112
+ defaults. Task exceptions remain task-local and cannot silently rewrite shared profile.
113
+
114
+ ## Reconciliation
115
+
116
+ Every decision and domain-documentation fingerprint source is rediscovered when accessible. Missing observations remain
117
+ unknown, never current proof. Changed fingerprint marks owning decision stale and
118
+ invalidates only transitive dependent closure. Repository facts are rediscovered;
119
+ user-owned conventions are re-interviewed. Proposed update accumulates outside shared
120
+ file. Rejection leaves shared profile byte-for-byte unchanged and creates no shared
121
+ stale marker.
122
+
123
+ Revision 1 creates profile. Update preserves `profileId`, increments revision exactly by
124
+ one, and must change content digest. Same-content and stale-revision publication fail.
125
+
126
+ ## Validation and publication
127
+
128
+ Candidate stdin may be raw profile YAML/JSON or transaction object:
129
+
130
+ ````yaml
131
+ profile: # profile proposal without approval
132
+ projections:
133
+ - path: .codex/dev-flow/diagrams/example-r1.mermaid.md
134
+ content: |-
135
+ ```mermaid
136
+ flowchart LR
137
+ A --> B
138
+ ```
139
+ ````
140
+
141
+ Validation is read-only and returns exact canonical proposal YAML, digest, revision,
142
+ decision/topology/stack diff, and projection paths. Agent shows adaptive summary and
143
+ exact YAML on request, then asks one explicit Profile Approval. Candidate or projection
144
+ change requires validation and approval again.
145
+
146
+ Before shared publication, existing INIT session—when present—must be
147
+ `awaiting_approval` and bound to same candidate content digest. This prevents resume or
148
+ candidate drift from inheriting prior validation.
149
+
150
+ After approval, backend publishes new immutable projection paths first and shared
151
+ profile through one final atomic rename. Shared profile rename is authority boundary;
152
+ failed rename leaves prior profile current, while any orphan new projection remains
153
+ non-authoritative. Existing projection path can be reused only with byte-identical
154
+ content. Symlinked profile or projection path is rejected. Local overlay uses separate
155
+ atomic write after ignore and authority validation.
156
+
157
+ Direct file write bypass is forbidden.
@@ -0,0 +1,291 @@
1
+ # Maintainer Release Runbook
2
+
3
+ ## Purpose and ownership
4
+
5
+ This runbook is the canonical production-release procedure for Dev Flow. A
6
+ maintainer runs it from a trusted local workstation. CI validates releases but does not
7
+ publish the canonical npm package or the Codex plugin. After an npm-bearing GitHub
8
+ Release is published, a separate GitHub Actions workflow mirrors its canonical npmjs
9
+ tarball to GitHub Packages as `@acrazie/dev-flow`.
10
+
11
+ Use the repository release program rather than invoking `npm publish`, creating tags,
12
+ or editing release versions manually:
13
+
14
+ ```bash
15
+ bun run release
16
+ ```
17
+
18
+ The release design and safety rationale are recorded in
19
+ [ADR 0008](../adr/0008-automate-maintainer-releases-with-an-interactive-bun-workflow.md).
20
+
21
+ ## Supported release targets
22
+
23
+ | Target | Version change | Tag | Publication |
24
+ | ------------ | ---------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------ |
25
+ | Plugin + npm | Increment npm SemVer; give plugin same base plus UTC cachebuster | `v<version>` | Git push, npm, GitHub Release, optional local plugin refresh |
26
+ | Codex plugin | Keep semantic base; replace plugin UTC cachebuster | `plugin-v<version>-codex.<cachebuster>` | Git push, GitHub Release, optional local plugin refresh |
27
+ | npm package | Increment npm SemVer; leave plugin manifest unchanged | `npm-v<version>` | Git push, npm, GitHub Release |
28
+
29
+ Only stable npm versions are supported. The program recommends patch, minor, or major
30
+ from Conventional Commits; maintainer retains final version authority.
31
+
32
+ ## Preconditions
33
+
34
+ - Run on Linux or macOS. Windows is rejected.
35
+ - Install Node.js 24 or newer.
36
+ - Install repository-pinned Bun version from root `package.json`.
37
+ - Install `git` and GitHub CLI `gh`.
38
+ - Have push permission for `origin/main` and release creation permission on GitHub.
39
+ - For npm or combined release, have publish permission for `@acrasie/dev-flow`.
40
+ - Keep `main` clean, with no staged, unstaged, or untracked files.
41
+ - Ensure local `main` can fast-forward to `origin/main`; release program never rebases,
42
+ resets, or creates a merge commit.
43
+
44
+ Authenticate without placing credentials in repository files:
45
+
46
+ ```bash
47
+ gh auth status
48
+ cd plugins/codex-dev-flow
49
+ bun pm whoami
50
+ cd ../..
51
+ ```
52
+
53
+ `bun pm whoami` is unnecessary for a plugin-only release. OTP, when required, remains
54
+ inside interactive `bun publish`.
55
+
56
+ ## Recommended procedure
57
+
58
+ ### 1. Prepare local `main`
59
+
60
+ ```bash
61
+ git switch main
62
+ git pull --ff-only
63
+ git status --short
64
+ ```
65
+
66
+ `git status --short` must produce no output. Do not stash unrelated work inside the
67
+ release procedure; finish or move it before starting.
68
+
69
+ ### 2. Run read-only preview
70
+
71
+ ```bash
72
+ bun run release
73
+ ```
74
+
75
+ Choose intended target, then **Preview only**. Preview still requires GitHub and, when
76
+ applicable, npm authentication plus network access. It checks version availability and
77
+ runs validation, but restores generated bundle bytes and changes no remote state.
78
+
79
+ Confirm preview shows expected:
80
+
81
+ - target;
82
+ - npm and plugin versions;
83
+ - tag and release identity;
84
+ - changed-file allowlist;
85
+ - publication order.
86
+
87
+ Preview requires local `main` to equal `origin/main`. If it refuses, reconcile with
88
+ `git pull --ff-only`, inspect result, then rerun preview.
89
+
90
+ ### 3. Publish
91
+
92
+ Run same command again, choose same target, then **Prepare and publish**:
93
+
94
+ ```bash
95
+ bun run release
96
+ ```
97
+
98
+ Before any publication, program performs:
99
+
100
+ 1. Git branch, cleanliness, synchronization, authentication, and version-availability
101
+ checks;
102
+ 2. frozen dependency installation;
103
+ 3. typecheck and deterministic build;
104
+ 4. main and release test suites;
105
+ 5. plugin-manifest validation;
106
+ 6. npm package inspection and publish dry-run when applicable;
107
+ 7. generated-file allowlist validation;
108
+ 8. release commit, annotated tag, and generated GitHub release-note preview.
109
+
110
+ Review final summary. Final publication confirmation defaults to **No**. Approval starts
111
+ publication in this order:
112
+
113
+ 1. atomically push release commit and tag;
114
+ 2. run `bun publish --access public` when target includes npm;
115
+ 3. create GitHub Release from generated notes;
116
+ 4. optionally refresh locally installed Codex plugin.
117
+
118
+ Publishing the GitHub Release asynchronously starts `Publish GitHub package mirror`
119
+ for combined `v<version>` and npm-only `npm-v<version>` tags. Plugin-only tags have no
120
+ npm artifact and do not start the mirror. The release program does not wait for or
121
+ include this asynchronous mirror in its partial-release state.
122
+
123
+ Start a new Codex thread after local plugin refresh so new plugin version loads.
124
+
125
+ ## Verification
126
+
127
+ Use tag printed by release program:
128
+
129
+ ```bash
130
+ git show --no-patch <tag>
131
+ gh release view <tag>
132
+ ```
133
+
134
+ For npm or combined target, use npm version printed by release program:
135
+
136
+ ```bash
137
+ npm view @acrasie/dev-flow@<version> version
138
+ ```
139
+
140
+ After the mirror workflow succeeds, an authenticated GitHub Packages client can verify
141
+ the scoped alias:
142
+
143
+ ```bash
144
+ npm view @acrazie/dev-flow@<version> version \
145
+ --registry=https://npm.pkg.github.com
146
+ ```
147
+
148
+ Expected final state:
149
+
150
+ - local and remote `main` point to release commit;
151
+ - annotated tag points to same commit;
152
+ - GitHub Release exists for tag;
153
+ - selected npm version exists when applicable;
154
+ - matching `@acrazie/dev-flow` version exists after the asynchronous mirror;
155
+ - worktree is clean.
156
+
157
+ The release commit, tag, npm registry entry, and GitHub Release are durable audit
158
+ records. No separate local release-state file exists.
159
+
160
+ ## Package rename
161
+
162
+ New releases target `@acrasie/dev-flow` on npmjs and `@acrazie/dev-flow` on GitHub Packages.
163
+ Historical `codex-dev-flow` releases remain separate; this workflow does not republish
164
+ or migrate them. Its `all` selector backfills only versions published as `@acrasie/dev-flow`.
165
+ The unscoped `dev-flow` publication was rejected by npm due to similarity to `devflow`.
166
+ The npm scope is `acrasie`, while the GitHub owner and mirror scope remain `acrazie`.
167
+ The CLI and Codex plugin identity remain `dev-flow`.
168
+ Before the first scoped release, verify npm name availability and publication rights
169
+ and set the new GitHub package visibility after its first publication. The retained
170
+ `codex-dev-flow` binary alias is included in the new package. No package is published
171
+ by the rename itself.
172
+
173
+ ## Initial GitHub Packages publication and historical backfill
174
+
175
+ The canonical package is now the public, scoped `@acrasie/dev-flow` package on npmjs.
176
+ GitHub Packages contains a scoped mirror because its npm registry accepts only scoped
177
+ names. Mirror input always comes from the already-published npmjs tarball; the workflow
178
+ validates source name, version, and repository, then changes only the package name.
179
+
180
+ Because this repository is private, the first linked GitHub package initially inherits
181
+ private visibility. To create the approved public mirror without racing the complete
182
+ backfill:
183
+
184
+ 1. Merge the mirror workflow to the default branch.
185
+ 2. Obtain separate authorization for package publication, then publish only the oldest
186
+ version:
187
+
188
+ ```bash
189
+ gh workflow run publish-github-package.yml -f versions=0.1.0
190
+ ```
191
+
192
+ 3. Wait for success. Open the new `@acrazie/dev-flow` package settings and change
193
+ visibility to **Public**. This UI operation is deliberately manual.
194
+ 4. Obtain confirmation immediately before the visibility change: making a GitHub
195
+ package public cannot be reversed.
196
+ 5. Backfill every stable npmjs version:
197
+
198
+ ```bash
199
+ gh workflow run publish-github-package.yml -f versions=all
200
+ ```
201
+
202
+ The `all` selector discovers stable npmjs versions, skips exact versions already present
203
+ in GitHub Packages, and publishes missing versions oldest first. A precise stable
204
+ version, `v<version>`, or `npm-v<version>` may also be dispatched for targeted recovery.
205
+ Publishing the public package exposes only content already present in the public npmjs
206
+ tarball; it does not make the private source repository readable.
207
+
208
+ ## Cancellation and failure recovery
209
+
210
+ ### Complete npm publication for an existing Release Please release
211
+
212
+ When Release Please has already merged a release PR and published its GitHub release,
213
+ but the corresponding npm version is missing, use:
214
+
215
+ ```bash
216
+ bun run release --publish-existing dev-flow-v1.0.1
217
+ ```
218
+
219
+ This mode verifies the published stable GitHub release, the local and remote tag commit,
220
+ and ancestry on `origin/main`. It exports that exact commit into a temporary directory,
221
+ requires its pinned Bun version, installs frozen workspace dependencies, runs release
222
+ validations and the full quality gate, and previews npm publication before confirmation.
223
+ The invoking checkout is not published, so it may contain the recovery-tool correction
224
+ on a dedicated branch. No version, plugin manifest, tag, or GitHub release is changed.
225
+ An already-published npm version is skipped. Only the missing npm publication is performed.
226
+
227
+ The existing GitHub release event is not emitted again. If a GitHub Packages mirror is
228
+ required, dispatch the repository mirror workflow for the exact npm version after npm
229
+ publication is verified; do not create another release.
230
+
231
+ ### Before first successful push
232
+
233
+ Cancellation, `Ctrl+C`, or validation failure restores original release files and
234
+ removes only commit or tag objects created by program. Inspect:
235
+
236
+ ```bash
237
+ git status --short
238
+ git log -1 --oneline
239
+ ```
240
+
241
+ Fix cause, ensure clean `main`, then restart with `bun run release`.
242
+
243
+ ### After push, npm publication, or GitHub publication begins
244
+
245
+ Do not delete remote tag, rewrite `main`, unpublish package, or create replacement
246
+ release manually. Published systems are not one atomic transaction and program never
247
+ attempts remote rollback.
248
+
249
+ Keep checkout on clean release commit and rerun:
250
+
251
+ ```bash
252
+ bun run release
253
+ ```
254
+
255
+ Program recognizes release commit, reconciles Git, npm, and GitHub state, displays
256
+ missing steps, then asks whether to resume. Already completed publication steps are
257
+ skipped. This also handles case where npm accepted package but local command lost its
258
+ response.
259
+
260
+ If all remote publication steps succeeded and only optional local plugin refresh
261
+ failed, do **not** rerun release solely for that refresh. Run it directly:
262
+
263
+ ```bash
264
+ codex plugin marketplace upgrade acrazie
265
+ codex plugin add dev-flow@acrazie
266
+ ```
267
+
268
+ Then start a new Codex thread.
269
+
270
+ If the asynchronous GitHub Packages mirror fails, do not create another npm or GitHub
271
+ Release. Rerun the failed Actions job or dispatch its exact stable version. Existing
272
+ destination versions are verified and skipped, so recovery is idempotent. Authentication,
273
+ network, malformed metadata, and unexpected registry responses block instead of being
274
+ treated as a missing version.
275
+
276
+ ### Bad release discovered after completion
277
+
278
+ Prefer forward correction: fix defect and publish a new patch or plugin-cachebuster
279
+ release. Published npm versions are immutable release identities and must never be
280
+ reused.
281
+
282
+ ## Forbidden shortcuts
283
+
284
+ - No validation bypass or force-publish path.
285
+ - No manual version edits followed by direct publish.
286
+ - No direct `npm publish` or `bun publish` of the canonical npmjs package outside the
287
+ release program. The repository-owned GitHub Packages mirror workflow is the only
288
+ scoped-alias exception.
289
+ - No manual tag or GitHub Release for a new release.
290
+ - No automatic or manual merge/rebase/reset inside release procedure.
291
+ - Never commit npm tokens, GitHub tokens, OTP values, or generated credential files.