@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.
- package/.codex-plugin/plugin.json +20 -0
- package/LICENSE +21 -0
- package/README.md +181 -2
- package/dist/codex-dev-flow.mjs +3 -0
- package/dist/dev-flow.mjs +241 -0
- package/docs/adr/0001-hybrid-portable-workflow.md +23 -0
- package/docs/adr/0002-share-an-invalidable-context-capsule.md +55 -0
- package/docs/adr/0004-scale-assurance-lanes-by-applicable-risk.md +36 -0
- package/docs/adr/0006-make-intake-adaptive-user-authoritative-and-token-efficient.md +76 -0
- package/docs/adr/0007-collect-opt-in-local-benchmark-feedback.md +82 -0
- package/docs/adr/0008-automate-maintainer-releases-with-an-interactive-bun-workflow.md +121 -0
- package/docs/adr/0009-separate-intake-decisions-from-shape-discovery.md +200 -0
- package/docs/adr/0010-choose-quick-or-plan-after-discovery.md +161 -0
- package/docs/adr/0011-separate-fast-local-and-authoritative-ci-quality-gates.md +49 -0
- package/docs/adr/0012-use-bun-test-and-require-node-24.md +41 -0
- package/docs/adr/0013-layer-source-distribution-and-runtime-tests.md +42 -0
- package/docs/adr/0014-ratchet-source-coverage-with-bun.md +51 -0
- package/docs/adr/0015-split-fast-and-type-aware-linting.md +41 -0
- package/docs/adr/0016-use-husky-with-a-tested-bun-staged-file-adapter.md +45 -0
- package/docs/adr/0017-format-conservatively-with-oxfmt.md +45 -0
- package/docs/adr/0018-use-a-high-signal-oxlint-policy.md +53 -0
- package/docs/adr/0019-gate-deterministic-size-and-observe-timing.md +44 -0
- package/docs/adr/0020-support-linux-and-macos-with-targeted-ci.md +41 -0
- package/docs/adr/0021-randomize-tests-without-retries.md +35 -0
- package/docs/adr/0022-use-one-root-bun-workspace.md +41 -0
- package/docs/adr/0024-make-gate-a-minimal-plan-approval.md +74 -0
- package/docs/adr/0025-end-the-lifecycle-after-assure.md +55 -0
- package/docs/adr/0026-keep-intake-product-stable-and-interview-shape-by-dependency.md +151 -0
- package/docs/adr/0027-add-agentic-project-init-and-versioned-engineering-profiles.md +147 -0
- package/docs/adr/0028-make-public-documentation-user-first-and-current.md +65 -0
- package/docs/adr/0029-make-build-a-native-execution-boundary.md +51 -0
- package/docs/adr/0030-unify-product-domain-and-technical-design-interviews.md +240 -0
- package/docs/adr/0031-make-assure-the-success-boundary.md +205 -0
- package/docs/artifacts.md +47 -0
- package/docs/baselines/2026-07-18-p0-lifecycle.json +142 -0
- package/docs/design.md +101 -0
- package/docs/getting-started.md +204 -0
- package/docs/glossary/dev-flow.md +527 -0
- package/docs/lifecycle-contract.md +189 -0
- package/docs/lifecycle-contract.projection.json +931 -0
- package/docs/metrics-protocol.md +113 -0
- package/docs/project-profile-contract.md +157 -0
- package/docs/runbooks/maintainer-release.md +291 -0
- package/docs/target-intake-shape-contract.md +416 -0
- package/package.json +68 -4
- package/schemas/config.schema.json +104 -0
- package/schemas/policy.schema.json +17 -0
- package/schemas/project-init-state.schema.json +159 -0
- package/schemas/project-profile-local.schema.json +53 -0
- package/schemas/project-profile.schema.json +285 -0
- package/schemas/state.schema.json +826 -0
- package/skills/debug-root-cause/SKILL.md +16 -0
- package/skills/design-decisions/SKILL.md +24 -0
- package/skills/dev-flow/SKILL.md +306 -0
- package/skills/dev-flow/agents/openai.yaml +6 -0
- package/skills/discover-change/SKILL.md +31 -0
- package/skills/plan-change/SKILL.md +29 -0
- package/skills/review-change/SKILL.md +21 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# ADR 0010: Choose Quick or Plan After Discovery
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted for current runtime. Replacement target sequencing is defined by ADR 0030;
|
|
6
|
+
ADR 0026 is superseded as target design.
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
The `quick`, `standard`, and `critical` mode set mixes preparation depth with risk.
|
|
11
|
+
Requiring a mode argument also asks the user to choose before repository discovery can
|
|
12
|
+
show whether detailed planning is useful.
|
|
13
|
+
|
|
14
|
+
Quick currently bypasses operational SHAPE and GATE work. That creates a second
|
|
15
|
+
workflow rather than a lower-cost execution of the same lifecycle, and lets BUILD own
|
|
16
|
+
localization or design work that belongs to SHAPE.
|
|
17
|
+
|
|
18
|
+
The user-facing distinction is simpler: after technical discovery, either project a
|
|
19
|
+
compact execution contract or emit a durable detailed plan. Safety remains independent.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
The invocation has no mode argument:
|
|
24
|
+
|
|
25
|
+
`$dev-flow <objective>`
|
|
26
|
+
|
|
27
|
+
Every task traverses all five operational phases:
|
|
28
|
+
|
|
29
|
+
`INTAKE -> SHAPE -> GATE -> BUILD -> ASSURE -> finished`
|
|
30
|
+
|
|
31
|
+
SHAPE contains two strictly separated roles with one explicit profile choice between
|
|
32
|
+
them:
|
|
33
|
+
|
|
34
|
+
`Discovery -> Quick|Plan choice -> Planning`
|
|
35
|
+
|
|
36
|
+
Discovery runs adaptively until `discovery_sufficient`. It then presents one structured,
|
|
37
|
+
evidence-backed preparation choice:
|
|
38
|
+
|
|
39
|
+
- **Quick:** project a compact canonical execution contract in workflow state.
|
|
40
|
+
- **Plan:** project a detailed canonical contract and one repository-versioned Markdown
|
|
41
|
+
plan containing the spec, implementation plan, and any required implementation
|
|
42
|
+
guidance.
|
|
43
|
+
|
|
44
|
+
The recommendation uses only fresh Discovery evidence. Quick is recommended for
|
|
45
|
+
localized, linear work with obvious validation. Plan is recommended for material
|
|
46
|
+
cross-surface dependencies, migration, non-obvious sequencing, coordination, or other
|
|
47
|
+
evidence that a durable artifact will reduce implementation drift. Policy may require
|
|
48
|
+
Plan and must explain the exact constraint rather than presenting a false choice.
|
|
49
|
+
|
|
50
|
+
An explicit initial request for a durable plan resolves Plan without a redundant
|
|
51
|
+
question. A policy lock resolves Plan with an explanation rather than a false choice.
|
|
52
|
+
Otherwise the workflow enters stable `awaiting_profile_choice`, persists the exact
|
|
53
|
+
Quick/Plan choice and evidence-backed recommendation, and requires an explicit user
|
|
54
|
+
answer. Silence cannot select the recommendation. Crash/resume restores the same choice
|
|
55
|
+
unless its Discovery inputs changed. Producing the choice uses the existing Discovery
|
|
56
|
+
result and does not require another model call.
|
|
57
|
+
|
|
58
|
+
The visible choice is a compact Discovery checkpoint, not an evidence dump. It states
|
|
59
|
+
the change shape, relevant surface count or categories, material dependency/migration/
|
|
60
|
+
validation facts, the recommendation, and one short evidence-backed reason. Full
|
|
61
|
+
Discovery evidence remains in state and is shown only on request.
|
|
62
|
+
|
|
63
|
+
The selected profile remains valid through later Planning-to-Discovery loops. New
|
|
64
|
+
technical complexity does not automatically ask the user again. Quick may gain whatever
|
|
65
|
+
internal contract detail correctness requires without becoming Plan, and Plan remains
|
|
66
|
+
Plan if later evidence simplifies the work. Only a fresh policy that forbids the
|
|
67
|
+
selection or an explicit user change invalidates the profile choice.
|
|
68
|
+
|
|
69
|
+
The profile choice happens before Planning and GATE. Choosing after all of SHAPE would
|
|
70
|
+
either make Quick pay for a detailed plan it discards or force Plan to reopen SHAPE.
|
|
71
|
+
Planning consumes the chosen profile and fresh Discovery evidence; it never rereads the
|
|
72
|
+
repository.
|
|
73
|
+
|
|
74
|
+
Quick and Plan share the same adaptive minimum Discovery required for safe executable
|
|
75
|
+
planning: relevant behavior, surfaces, dependencies, repository constraints, validation
|
|
76
|
+
commands, and material risks. Quick never saves tokens by moving unresolved technical
|
|
77
|
+
discovery into BUILD.
|
|
78
|
+
|
|
79
|
+
Plan may cause later targeted Discovery only when detailed Planning exposes a missing
|
|
80
|
+
fact needed by the durable contract. It cannot widen discovery merely to add explanatory
|
|
81
|
+
prose. Any evidence required for correctness, safety, or risk controls belongs to the
|
|
82
|
+
common minimum and is therefore required for Quick too.
|
|
83
|
+
|
|
84
|
+
Preparation profile controls artifact depth only. Risk and policy independently control
|
|
85
|
+
safeguards, approvals, worktree requirements, threat modeling, rollback planning,
|
|
86
|
+
assurance lanes, and other safety controls. The old Critical mode disappears; critical
|
|
87
|
+
remains a valid risk level.
|
|
88
|
+
|
|
89
|
+
This redesign uses a hard schema break. Legacy `quick`, `standard`, and `critical` task
|
|
90
|
+
states, invocations, approvals, artifacts, and receipts are not migrated or accepted as
|
|
91
|
+
current workflow evidence. Implementation replaces old mode branches directly rather
|
|
92
|
+
than carrying compatibility aliases or migration paths. Existing adaptive INTAKE
|
|
93
|
+
semantics remain, but its contract stops owning mode and hands risk plus product context
|
|
94
|
+
to SHAPE.
|
|
95
|
+
|
|
96
|
+
Quick and Plan share one contract schema. Quick's compact completion profile requires
|
|
97
|
+
Intake references, affected surfaces, testable acceptance criteria, ordered execution
|
|
98
|
+
steps, criterion-linked validation, applicable risks, and explicit dependencies. It
|
|
99
|
+
does not repeat Intake or Discovery prose.
|
|
100
|
+
|
|
101
|
+
Quick omits the Markdown projection, long rationale, obvious non-goals, a detailed task
|
|
102
|
+
DAG when linear order is sufficient, and implementation guidance without a material
|
|
103
|
+
architectural constraint. The smallest valid contract may contain one criterion, one
|
|
104
|
+
execution step, and one validation. Compactness cannot remove coverage, freshness, or
|
|
105
|
+
risk-driven requirements.
|
|
106
|
+
|
|
107
|
+
Plan uses the same logical structure at greater depth:
|
|
108
|
+
|
|
109
|
+
- **Spec:** expected behavior, scope, non-goals, and acceptance criteria.
|
|
110
|
+
- **Plan:** atomic tasks, dependencies, and verification mapping.
|
|
111
|
+
- **Implementation Guide:** only evidence-backed architectural constraints, patterns,
|
|
112
|
+
migration rules, or sequencing details needed to prevent implementation drift.
|
|
113
|
+
|
|
114
|
+
Planning creates an Implementation Guide only when evidence proves at least one material
|
|
115
|
+
implementation constraint: an architectural boundary, compatible API/schema/data
|
|
116
|
+
migration, non-obvious execution ordering, security/concurrency/performance invariant,
|
|
117
|
+
mandatory repository pattern not inferable from tasks, or complex rollback/deployment.
|
|
118
|
+
The contract records `guideRequiredBecause` references to supporting evidence or risks.
|
|
119
|
+
Without an admissible linked reason, the section is absent rather than rendered as
|
|
120
|
+
`N/A`.
|
|
121
|
+
|
|
122
|
+
The structured contract in workflow state is canonical. Plan automatically projects it
|
|
123
|
+
to one repository-versioned Markdown document. The projection is generated from
|
|
124
|
+
canonical fields and is never an independently edited second source of truth. Its
|
|
125
|
+
default location is `docs/dev-flow/YYYY-MM-DD-<slug>.md`; repository configuration or
|
|
126
|
+
policy may select another native representation or location.
|
|
127
|
+
|
|
128
|
+
Planning renders the document as `Proposed` before GATE. Approval binds the canonical
|
|
129
|
+
logical digest, then projection status becomes `Approved` without changing contract
|
|
130
|
+
content. A manual projection edit triggers explicit Planning reconciliation; the
|
|
131
|
+
workflow neither imports nor overwrites it silently.
|
|
132
|
+
|
|
133
|
+
GATE always executes and binds explicit user approval to canonical logical digest for
|
|
134
|
+
both profiles. Its current contract is defined by ADR 0024.
|
|
135
|
+
|
|
136
|
+
BUILD always consumes the exact current SHAPE contract and never performs hidden
|
|
137
|
+
shaping. ADR 0029 reduces it to native Codex execution with no separate skill or
|
|
138
|
+
validation loop. ASSURE scales by applicable risk rather than profile and reaches
|
|
139
|
+
`finished` directly under ADR 0025.
|
|
140
|
+
|
|
141
|
+
## Consequences
|
|
142
|
+
|
|
143
|
+
- The common invocation is one short command with no mode vocabulary.
|
|
144
|
+
- Recommendation quality improves because repository complexity is known before choice.
|
|
145
|
+
- Explicit plan requests and policy locks avoid redundant questions; all other choices
|
|
146
|
+
remain user-authoritative and resumable.
|
|
147
|
+
- Quick pays only for necessary discovery and compact planning while still traversing
|
|
148
|
+
every lifecycle phase.
|
|
149
|
+
- Quick avoids hidden BUILD-time shaping; Plan spends extra Discovery tokens only on
|
|
150
|
+
evidence genuinely required by its durable contract.
|
|
151
|
+
- Quick and Plan share contract parsing, BUILD approval/digest boundary, and ASSURE
|
|
152
|
+
completion guards.
|
|
153
|
+
- Plan produces one predictable review artifact without splitting spec, plan, and
|
|
154
|
+
guidance into drift-prone files.
|
|
155
|
+
- The state machine needs a stable SHAPE state for the explicit profile choice.
|
|
156
|
+
- The state machine no longer needs Standard- or Critical-only mode paths, but retains
|
|
157
|
+
critical risk semantics.
|
|
158
|
+
- Invocation parsing, configuration, schemas, migration, docs, tests, metrics, and
|
|
159
|
+
benchmarks must replace task mode with a post-Discovery preparation profile.
|
|
160
|
+
- Existing in-progress state becomes intentionally incompatible; the new schema and
|
|
161
|
+
validators must fail it clearly instead of guessing a conversion.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# ADR 0011: Separate Fast Local and Authoritative CI Quality Gates
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The plugin needs automated formatting, linting, type checking, building, and testing
|
|
10
|
+
without making normal commits progressively slower as the repository grows.
|
|
11
|
+
|
|
12
|
+
A Git hook is useful for immediate feedback but is local, optional, and bypassable. It
|
|
13
|
+
cannot be the sole owner of release or merge correctness. Running every validation on
|
|
14
|
+
every commit would also couple commit latency to the future size of the complete test
|
|
15
|
+
suite.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Use two quality gates with different latency and authority contracts:
|
|
20
|
+
|
|
21
|
+
- The **Fast Gate** runs before a commit, checks only staged supported files, performs
|
|
22
|
+
formatting and linting checks, does not mutate files, and targets sub-two-second
|
|
23
|
+
feedback.
|
|
24
|
+
- The **Full Gate** runs in CI over the complete repository and performs formatting,
|
|
25
|
+
linting, type checking, build validation, the complete automated test suite, and
|
|
26
|
+
distribution smoke checks.
|
|
27
|
+
|
|
28
|
+
The Fast Gate is developer feedback, not authoritative proof. CI remains the required
|
|
29
|
+
source of quality evidence even when the local hook succeeds or is bypassed.
|
|
30
|
+
|
|
31
|
+
Both gates cover the repository as one quality scope. Formatting includes supported
|
|
32
|
+
source, configuration, schema, workflow, and documentation files at the repository root
|
|
33
|
+
and under the plugin package. Linting applies to supported JavaScript and TypeScript
|
|
34
|
+
files across the same scope. Generated, vendored, cached, lock, and distribution files
|
|
35
|
+
are excluded explicitly where the tool does not already exclude them safely.
|
|
36
|
+
|
|
37
|
+
Package scripts own both gate commands. Any Git-hook tool is only an adapter that calls
|
|
38
|
+
those scripts and contains no independent quality policy.
|
|
39
|
+
|
|
40
|
+
## Consequences
|
|
41
|
+
|
|
42
|
+
- Commit latency stays bounded as the full test suite grows.
|
|
43
|
+
- Root documentation and configuration cannot drift from plugin formatting policy.
|
|
44
|
+
- A commit may exist locally before all tests run; merge safety therefore depends on
|
|
45
|
+
required CI.
|
|
46
|
+
- Staged-file selection must be path-safe and must not silently omit supported renamed
|
|
47
|
+
or copied files.
|
|
48
|
+
- Developers need an explicit command to run the Full Gate before pushing when desired.
|
|
49
|
+
- Hook installation or bypass behavior cannot change CI validation semantics.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ADR 0012: Use Bun Test and Require Node 24
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The test suite currently mixes `node:test` for most tests with `bun:test` for release
|
|
10
|
+
tests. Maintaining two runner APIs and two test commands adds complexity. The published
|
|
11
|
+
CLI executes on Node.js, while Bun already serves as the repository package manager and
|
|
12
|
+
script runner.
|
|
13
|
+
|
|
14
|
+
Node.js 22 remains in Maintenance LTS until April 30, 2027, but retaining it expands the
|
|
15
|
+
CI matrix and constrains use of newer runtime facilities. Node.js 24 has a longer support
|
|
16
|
+
horizon and is sufficient for the plugin's intended users.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
|
|
20
|
+
Use `bun:test` as the sole automated test-suite runner and migrate existing `node:test`
|
|
21
|
+
tests to its native API.
|
|
22
|
+
|
|
23
|
+
Raise the published runtime floor from Node.js `>=22.18.0` to Node.js `>=24.0.0`. Remove
|
|
24
|
+
Node.js 22 from the CI matrix and repository compatibility contract.
|
|
25
|
+
|
|
26
|
+
The Full Gate supplements Bun test execution with a narrow Node.js 24 Runtime Smoke
|
|
27
|
+
Suite. After building and packaging, that suite uses the real Node binary to import the
|
|
28
|
+
bundle, execute the CLI, validate configuration, and execute the package-manager binary
|
|
29
|
+
symlink. It tests the published runtime boundary without duplicating the complete Bun
|
|
30
|
+
test suite.
|
|
31
|
+
|
|
32
|
+
## Consequences
|
|
33
|
+
|
|
34
|
+
- Test files may use Bun's native TypeScript, mocks, snapshots, watch mode, randomized
|
|
35
|
+
ordering, and coverage without another test framework.
|
|
36
|
+
- The Full Gate needs one test command instead of separate Node and Bun suites.
|
|
37
|
+
- Users on Node.js 22 must upgrade even though that release remains maintained upstream.
|
|
38
|
+
- Bun test execution cannot, by itself, prove compatibility with the Node.js runtime;
|
|
39
|
+
the narrow Runtime Smoke Suite supplies that evidence at the distribution boundary.
|
|
40
|
+
- The smoke suite must remain small and contract-focused. General behavior belongs in
|
|
41
|
+
the Bun test suite and is not duplicated under Node.js.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ADR 0013: Layer Source, Distribution, and Runtime Tests
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Twenty-six of the repository's twenty-seven JavaScript test files import the generated
|
|
10
|
+
`dist/dev-flow.mjs` bundle. This gives broad distribution fidelity but couples nearly
|
|
11
|
+
every failure to the build artifact, makes failures less local, and prevents useful
|
|
12
|
+
source-oriented coverage.
|
|
13
|
+
|
|
14
|
+
Testing only source modules would be faster but could miss bundling, packaging, binary,
|
|
15
|
+
and Node.js compatibility regressions.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Partition automated tests into three explicit layers:
|
|
20
|
+
|
|
21
|
+
1. **Unit Test Layer:** `bun:test` files import `src/*.ts` directly and validate isolated
|
|
22
|
+
deterministic behavior, boundary conditions, and failure contracts.
|
|
23
|
+
2. **Integration Test Layer:** `bun:test` files exercise the built bundle and complete
|
|
24
|
+
workflows where module composition or generated artifacts are material.
|
|
25
|
+
3. **Runtime Smoke Suite:** a narrow Node.js 24 suite exercises the packed distribution
|
|
26
|
+
boundary as defined by ADR 0012.
|
|
27
|
+
|
|
28
|
+
Move tests to the lowest layer that can prove their contract. Do not repeat the same
|
|
29
|
+
behavior across layers merely to increase counts or coverage.
|
|
30
|
+
|
|
31
|
+
No additional test framework, transpiler, or coverage service is introduced. Bun owns
|
|
32
|
+
TypeScript test execution and the main test API.
|
|
33
|
+
|
|
34
|
+
## Consequences
|
|
35
|
+
|
|
36
|
+
- Most deterministic logic can run without rebuilding the distribution.
|
|
37
|
+
- Failures identify source behavior or distribution composition more precisely.
|
|
38
|
+
- Source coverage becomes meaningful.
|
|
39
|
+
- Integration tests retain evidence for bundle exports and workflow composition.
|
|
40
|
+
- Test naming and scripts must make layer ownership visible.
|
|
41
|
+
- Refactoring the current suite requires classifying existing cases rather than
|
|
42
|
+
mechanically changing imports.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ADR 0014: Ratchet Source Coverage with Bun
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The existing bundle-first suite cannot provide representative TypeScript source
|
|
10
|
+
coverage. Selecting a fixed percentage before migrating tests would create an arbitrary
|
|
11
|
+
target and could reward low-value tests written only to satisfy the number.
|
|
12
|
+
|
|
13
|
+
Coverage still provides useful regression evidence when its scope is stable and its
|
|
14
|
+
floor cannot silently decrease.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
Use Bun's built-in coverage reporting and threshold enforcement. Do not add a hosted
|
|
19
|
+
coverage service or third-party instrumentation dependency.
|
|
20
|
+
|
|
21
|
+
After the layered test migration from ADR 0013:
|
|
22
|
+
|
|
23
|
+
1. Measure lines, functions, and statements for maintained `src/**/*.ts` files.
|
|
24
|
+
2. Exclude tests, generated output, distribution files, fixtures, and vendored files.
|
|
25
|
+
3. Set the initial enforced thresholds from the measured baseline, rounded down only
|
|
26
|
+
enough to avoid nondeterministic decimal noise.
|
|
27
|
+
4. Reject any later change that falls below an enforced threshold.
|
|
28
|
+
5. Raise thresholds when durable new coverage permits it. Never lower them without an
|
|
29
|
+
explicit documented decision explaining lost executable behavior or a corrected
|
|
30
|
+
measurement scope.
|
|
31
|
+
|
|
32
|
+
Coverage is a Full Gate signal. The Fast Gate does not collect it.
|
|
33
|
+
|
|
34
|
+
## Consequences
|
|
35
|
+
|
|
36
|
+
- Coverage cannot regress silently after the source-test migration.
|
|
37
|
+
- Initial thresholds reflect repository reality rather than an arbitrary percentage.
|
|
38
|
+
- CI stays self-contained and lightweight.
|
|
39
|
+
- Coverage does not replace behavior contracts, boundary tests, integration tests, or
|
|
40
|
+
the Runtime Smoke Suite.
|
|
41
|
+
- Test or source-scope changes that legitimately alter measurement require an explicit
|
|
42
|
+
baseline review.
|
|
43
|
+
|
|
44
|
+
## Implementation note
|
|
45
|
+
|
|
46
|
+
Bun 1.3.14 reports and enforces line and function coverage, but its installed text and
|
|
47
|
+
LCOV reporters do not expose statement coverage and its documented statement threshold
|
|
48
|
+
key does not affect the gate. PR2 therefore records statement coverage as unavailable
|
|
49
|
+
rather than claiming a false signal. Per-file line and function floors are enforced and
|
|
50
|
+
the measured aggregate is recorded. Statement enforcement remains required when Bun
|
|
51
|
+
exposes a verifiable metric.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ADR 0015: Split Fast and Type-Aware Linting
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The pre-commit gate needs consistently low latency. The Full Gate also needs semantic
|
|
10
|
+
TypeScript lint rules, such as unhandled-promise checks, that syntax-only linting and the
|
|
11
|
+
TypeScript compiler do not provide alone.
|
|
12
|
+
|
|
13
|
+
Oxlint type-aware linting requires the additional `oxlint-tsgolint` development package
|
|
14
|
+
and remains an evolving feature. Oxlint's integrated type checking is experimental and
|
|
15
|
+
is not yet a sufficient replacement for the repository's TypeScript compiler contract.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Use two Oxlint execution profiles:
|
|
20
|
+
|
|
21
|
+
- The Fast Gate runs native Oxlint rules without type-aware analysis over staged
|
|
22
|
+
JavaScript and TypeScript files.
|
|
23
|
+
- The Full Gate runs Oxlint with type-aware rules over the repository and separately
|
|
24
|
+
runs `tsc --noEmit`.
|
|
25
|
+
|
|
26
|
+
Install `oxlint-tsgolint` only as a development dependency. Do not enable Oxlint's
|
|
27
|
+
experimental `--type-check` mode and do not remove TypeScript compiler validation.
|
|
28
|
+
|
|
29
|
+
Both profiles consume one versioned Oxlint configuration. Differences in analysis mode
|
|
30
|
+
belong in repository scripts, not duplicated rule configurations.
|
|
31
|
+
|
|
32
|
+
## Consequences
|
|
33
|
+
|
|
34
|
+
- Commit feedback avoids type-program construction cost.
|
|
35
|
+
- CI detects semantic lint failures that syntax-only rules and `tsc` may miss.
|
|
36
|
+
- The development installation gains one native tooling dependency, but the published
|
|
37
|
+
package remains unchanged.
|
|
38
|
+
- Full linting and type checking intentionally overlap where independent tools can catch
|
|
39
|
+
different defects.
|
|
40
|
+
- Upgrades to evolving type-aware rules require reviewing new diagnostics rather than
|
|
41
|
+
silently weakening the configured rules.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ADR 0016: Use Husky with a Tested Bun Staged-File Adapter
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The Fast Gate needs the exact set of staged, supported files. Husky installs and invokes
|
|
10
|
+
Git hooks but does not own robust staged-file discovery. Shell word splitting is unsafe
|
|
11
|
+
for valid paths containing whitespace or newline characters.
|
|
12
|
+
|
|
13
|
+
`lint-staged` supplies mature file selection and argument handling, but its mutation,
|
|
14
|
+
backup, and restoration features are unnecessary for a check-only gate. Adding it would
|
|
15
|
+
also add another dependency and configuration surface.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Install Husky at the Git repository root as the pre-commit hook adapter. The hook
|
|
20
|
+
contains only a call to the root `check:staged` package script.
|
|
21
|
+
|
|
22
|
+
Implement `check:staged` as a small tested Bun script that:
|
|
23
|
+
|
|
24
|
+
1. obtains added, copied, modified, and renamed staged paths from Git with NUL-delimited
|
|
25
|
+
output;
|
|
26
|
+
2. excludes deletions and configured generated, vendored, cached, lock, and distribution
|
|
27
|
+
paths;
|
|
28
|
+
3. classifies supported formatter files separately from JavaScript and TypeScript lint
|
|
29
|
+
files;
|
|
30
|
+
4. invokes Oxfmt in check mode and native Oxlint without shell interpolation;
|
|
31
|
+
5. batches arguments or falls back safely before platform argument limits;
|
|
32
|
+
6. preserves tool exit status; and
|
|
33
|
+
7. never edits a file or the Git index.
|
|
34
|
+
|
|
35
|
+
Do not add `lint-staged`. Test path parsing, classification, batching, empty sets,
|
|
36
|
+
renames, unusual valid path characters, and failing child-process status.
|
|
37
|
+
|
|
38
|
+
## Consequences
|
|
39
|
+
|
|
40
|
+
- The Fast Gate adds Husky but no staged-file orchestration dependency.
|
|
41
|
+
- Repository code owns a small security- and correctness-sensitive adapter and must test
|
|
42
|
+
it as production-quality tooling.
|
|
43
|
+
- Hook behavior remains a thin projection of package scripts and cannot diverge into a
|
|
44
|
+
second quality policy.
|
|
45
|
+
- Check-only behavior avoids partial-staging backup and restoration complexity.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ADR 0017: Format Conservatively with Oxfmt
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Repository-wide formatting should remove presentation drift without introducing
|
|
10
|
+
unrelated ordering changes or rewriting documentation prose. Oxfmt enables package JSON
|
|
11
|
+
sorting by default and offers optional import sorting, but either behavior expands the
|
|
12
|
+
initial migration and can obscure review of the formatting adoption.
|
|
13
|
+
|
|
14
|
+
Import order can also be observable for modules with side effects. Formatting does not
|
|
15
|
+
need to own that policy.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Commit one explicit JSON Oxfmt configuration at the repository root with conservative,
|
|
20
|
+
stable choices:
|
|
21
|
+
|
|
22
|
+
- `printWidth: 100`
|
|
23
|
+
- `semi: true`
|
|
24
|
+
- `singleQuote: false`
|
|
25
|
+
- `trailingComma: "all"`
|
|
26
|
+
- `proseWrap: "preserve"`
|
|
27
|
+
- `sortImports: false`
|
|
28
|
+
- `sortPackageJson: false`
|
|
29
|
+
|
|
30
|
+
Use the same configuration in editors, the Fast Gate, and the Full Gate. Apply the
|
|
31
|
+
initial repository-wide formatting change in a dedicated commit so later functional
|
|
32
|
+
diffs are not mixed with formatter churn.
|
|
33
|
+
|
|
34
|
+
Import and manifest ordering remain outside formatter ownership unless a later decision
|
|
35
|
+
adds them with dedicated compatibility evidence.
|
|
36
|
+
|
|
37
|
+
## Consequences
|
|
38
|
+
|
|
39
|
+
- Source, configuration, schema, workflow, and documentation layout becomes
|
|
40
|
+
deterministic without broad ordering churn.
|
|
41
|
+
- Markdown prose retains author-selected wrapping where possible.
|
|
42
|
+
- Package manifests keep their intentional field order.
|
|
43
|
+
- Imports with side effects retain their authored order.
|
|
44
|
+
- More configuration is explicit, reducing reliance on tool defaults that may differ
|
|
45
|
+
from Prettier or change across tooling generations.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# ADR 0018: Use a High-Signal Oxlint Policy
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Oxlint's default correctness category is intentionally small. Enabling every available
|
|
10
|
+
category would increase noise, style debate, and false-positive pressure. The repository
|
|
11
|
+
needs defects and likely defects to block changes without turning linting into a broad
|
|
12
|
+
code-style policy already owned by Oxfmt.
|
|
13
|
+
|
|
14
|
+
Oxlint may add diagnostics in minor releases without treating them as breaking changes.
|
|
15
|
+
Unpinned upgrades could therefore change the gate unexpectedly.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Configure one high-signal repository-wide policy:
|
|
20
|
+
|
|
21
|
+
- `correctness`, `suspicious`, and `perf` diagnostics are blocking;
|
|
22
|
+
- `pedantic`, `style`, `restriction`, and `nursery` categories are disabled initially;
|
|
23
|
+
- unused Oxlint disable directives are blocking;
|
|
24
|
+
- the gate permits zero warnings; and
|
|
25
|
+
- Oxlint and `oxlint-tsgolint` use exact versions recorded in the lockfile.
|
|
26
|
+
|
|
27
|
+
Tool upgrades are explicit review events. Review newly activated diagnostics and fix or
|
|
28
|
+
document specific rule exceptions; never weaken a whole high-signal category merely to
|
|
29
|
+
complete an upgrade.
|
|
30
|
+
|
|
31
|
+
Oxfmt owns formatting. Oxlint style rules remain disabled unless a later behavior-driven
|
|
32
|
+
decision establishes value not already supplied by deterministic formatting.
|
|
33
|
+
|
|
34
|
+
Initial compatibility exceptions stay narrow and documented in `.oxlintrc.json`:
|
|
35
|
+
|
|
36
|
+
- `typescript/no-unsafe-type-assertion` is disabled because validated runtime boundaries
|
|
37
|
+
intentionally narrow unknown data after deterministic schema checks;
|
|
38
|
+
- `eslint/no-await-in-loop` is disabled only in files whose prompts, filesystem changes,
|
|
39
|
+
or release operations must remain sequential; and
|
|
40
|
+
- `typescript/no-floating-promises` is disabled only for test files, where test
|
|
41
|
+
registration calls intentionally return promises that the runner owns.
|
|
42
|
+
|
|
43
|
+
These exceptions do not disable their parent high-signal categories. Revisit them when
|
|
44
|
+
the affected APIs or Oxlint analysis improve.
|
|
45
|
+
|
|
46
|
+
## Consequences
|
|
47
|
+
|
|
48
|
+
- Likely defects and performance footguns fail both applicable gates.
|
|
49
|
+
- Style and experimental diagnostics do not create routine noise.
|
|
50
|
+
- Exact versioning keeps local and CI results reproducible.
|
|
51
|
+
- Dependency upgrades may require intentional code fixes or narrow documented rule
|
|
52
|
+
exceptions.
|
|
53
|
+
- The repository must review the rule configuration as Oxlint's stable coverage grows.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ADR 0019: Gate Deterministic Size and Observe Timing
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The plugin aims to remain performant and lightweight. Artifact size is deterministic
|
|
10
|
+
enough for a blocking CI contract, while wall-clock measurements on shared CI runners
|
|
11
|
+
vary with host load and can make an otherwise correct gate flaky.
|
|
12
|
+
|
|
13
|
+
The current bundle is 805,435 bytes and the pre-migration Full Gate completes in about
|
|
14
|
+
1.54 seconds on one maintainer machine. These are observations, not yet portable
|
|
15
|
+
thresholds.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
After the quality-toolchain migration, measure and commit baselines for:
|
|
20
|
+
|
|
21
|
+
- uncompressed `dist/dev-flow.mjs` bytes;
|
|
22
|
+
- packed npm tarball bytes; and
|
|
23
|
+
- unpacked npm package bytes.
|
|
24
|
+
|
|
25
|
+
Create deterministic blocking budgets from those baselines with explicit headroom
|
|
26
|
+
recorded alongside each value. A change may update a size budget only with a reviewed
|
|
27
|
+
explanation of the user-visible capability or required asset responsible for the growth.
|
|
28
|
+
|
|
29
|
+
Record Fast Gate, Full Gate, and cold CLI-start timing observations. Do not make timing
|
|
30
|
+
blocking until repeated CI data establishes a stable measurement method and a threshold
|
|
31
|
+
with enough tolerance to avoid runner-noise failures.
|
|
32
|
+
|
|
33
|
+
Do not combine timing and size into one score. A deterministic size regression remains
|
|
34
|
+
blocking even when execution happens to become faster.
|
|
35
|
+
|
|
36
|
+
## Consequences
|
|
37
|
+
|
|
38
|
+
- Artifact growth becomes visible and reviewable.
|
|
39
|
+
- Shared-runner timing noise cannot fail otherwise correct changes initially.
|
|
40
|
+
- Performance timing remains observable and can become a ratcheted gate after a stable
|
|
41
|
+
baseline exists.
|
|
42
|
+
- Size-budget updates require explicit review rather than an unexplained baseline reset.
|
|
43
|
+
- The implementation must define reproducible pack inputs before capturing package
|
|
44
|
+
budgets.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ADR 0020: Support Linux and macOS with Targeted CI
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The plugin describes itself as portable. Existing release policy guarantees the
|
|
10
|
+
maintainer workflow on macOS, treats Linux as best-effort, and explicitly does not claim
|
|
11
|
+
Windows support. Running the complete quality toolchain on every operating system would
|
|
12
|
+
increase CI cost without equal value for platform-independent checks.
|
|
13
|
+
|
|
14
|
+
Ubuntu-only CI would leave the existing macOS release guarantee dependent on manual
|
|
15
|
+
maintainer testing.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
Define Linux and macOS as the supported platform contract. Windows remains explicitly
|
|
20
|
+
unsupported until a later decision supplies compatible behavior and CI evidence.
|
|
21
|
+
|
|
22
|
+
Use targeted GitHub Actions jobs:
|
|
23
|
+
|
|
24
|
+
- run the complete Bun Full Gate, coverage, lint, typecheck, build, size, and package
|
|
25
|
+
checks on Ubuntu;
|
|
26
|
+
- run the Node.js 24 Runtime Smoke Suite on Ubuntu and macOS; and
|
|
27
|
+
- run maintainer-release integration tests on macOS in addition to their primary Bun
|
|
28
|
+
execution on Ubuntu.
|
|
29
|
+
|
|
30
|
+
Do not duplicate platform-independent formatting, linting, type checking, coverage, or
|
|
31
|
+
unit tests across operating systems.
|
|
32
|
+
|
|
33
|
+
## Consequences
|
|
34
|
+
|
|
35
|
+
- Published runtime and maintainer release behavior gain automated Linux/macOS evidence.
|
|
36
|
+
- CI cost stays below a full operating-system matrix.
|
|
37
|
+
- Platform-specific failures are localized to narrow jobs.
|
|
38
|
+
- Windows users receive no compatibility guarantee and documentation must say so
|
|
39
|
+
directly.
|
|
40
|
+
- Adding Windows later requires path, process, symlink, permission, and release-contract
|
|
41
|
+
evidence before changing the support claim.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ADR 0021: Randomize Tests Without Retries
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Bun executes the test suite in one process. Fixed discovery order can hide shared-state,
|
|
10
|
+
fixture, environment, or cleanup dependencies between tests. Automatic retries make CI
|
|
11
|
+
appear stable while masking those defects.
|
|
12
|
+
|
|
13
|
+
Bun reports the seed used for randomized test order and accepts that seed for exact
|
|
14
|
+
reproduction.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
Run the Bun test suite in CI with randomized ordering and preserve the reported seed in
|
|
19
|
+
job logs. Do not enable global or per-test automatic retries as a normal gate policy.
|
|
20
|
+
|
|
21
|
+
Every randomized failure is a real failure. Reproduce it with the emitted seed, remove
|
|
22
|
+
the order dependency or leaked state, and add a regression test where useful.
|
|
23
|
+
|
|
24
|
+
Use repeated execution only in an explicit periodic stress job or during diagnosis. A
|
|
25
|
+
passing retry cannot replace the original failing Full Gate result.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- CI continually probes order independence at negligible dependency cost.
|
|
30
|
+
- A failure remains reproducible through its recorded seed.
|
|
31
|
+
- Tests must isolate temporary files, processes, environment variables, clocks, and
|
|
32
|
+
global state.
|
|
33
|
+
- Intermittent failures cannot be hidden by retry-until-green behavior.
|
|
34
|
+
- Periodic repeated execution can detect low-probability failures without making every
|
|
35
|
+
pull request pay the same cost.
|