@afokapu/atdd-bun 0.10.39 → 0.10.41
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/conventions/_profiles/coder.yaml +72 -0
- package/conventions/_profiles/metrics.yaml +70 -0
- package/conventions/coder.bun/coder.bun.boundaries-http-client.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.commons-application-no-integration.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.commons-cross-feature-imports-in.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.commons-domain-no-framework-import.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.commons-domain-no-outbound.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.complexity-cyclomatic.convention.yaml +25 -4
- package/conventions/coder.bun/coder.bun.complexity-length.convention.yaml +26 -1
- package/conventions/coder.bun/coder.bun.complexity-nesting.convention.yaml +24 -4
- package/conventions/coder.bun/coder.bun.composition-consumer.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.composition-root.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.dead-code-reachability.convention.yaml +25 -1
- package/conventions/coder.bun/coder.bun.design-connected.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.design-dependency-flow.convention.yaml +17 -2
- package/conventions/coder.bun/coder.bun.design-hierarchy-import.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.design-orphan-export.convention.yaml +17 -2
- package/conventions/coder.bun/coder.bun.design-primitives.convention.yaml +17 -2
- package/conventions/coder.bun/coder.bun.design-token-color.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.design-token-hardcoded.convention.yaml +17 -2
- package/conventions/coder.bun/coder.bun.design-tokens-pure.convention.yaml +18 -2
- package/conventions/coder.bun/coder.bun.design-wagons-import.convention.yaml +18 -2
- package/conventions/coder.bun/coder.bun.dto-mapper.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.dto-placement.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.dto-purity.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml +25 -1
- package/conventions/coder.bun/coder.bun.green-header-order.convention.yaml +15 -7
- package/conventions/coder.bun/coder.bun.green-header-purpose.convention.yaml +16 -5
- package/conventions/coder.bun/coder.bun.green-header-runtime.convention.yaml +15 -6
- package/conventions/coder.bun/coder.bun.green-header-tested-by.convention.yaml +16 -11
- package/conventions/coder.bun/coder.bun.green-urn-layer.convention.yaml +16 -4
- package/conventions/coder.bun/coder.bun.green-urn-marker.convention.yaml +16 -9
- package/conventions/coder.bun/coder.bun.green-urn-name-matches.convention.yaml +16 -5
- package/conventions/coder.bun/coder.bun.green-urn-pattern.convention.yaml +16 -4
- package/conventions/coder.bun/coder.bun.green-urn-side.convention.yaml +15 -6
- package/conventions/coder.bun/coder.bun.green-urn-wagon-feature.convention.yaml +15 -6
- package/conventions/coder.bun/coder.bun.layer-naming.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.phase-discipline.convention.yaml +111 -0
- package/conventions/coder.bun/coder.bun.quality-comments.convention.yaml +25 -1
- package/conventions/coder.bun/coder.bun.quality-mi.convention.yaml +25 -1
- package/conventions/coder.bun/coder.bun.responsive-breakpoints-declared.convention.yaml +17 -2
- package/conventions/coder.bun/coder.bun.responsive-no-fixed-width.convention.yaml +17 -1
- package/conventions/coder.bun/coder.bun.responsive-viewport-meta.convention.yaml +16 -1
- package/conventions/coder.bun/coder.bun.runtime-server-is-bun-serve.convention.yaml +16 -13
- package/conventions/coder.bun/coder.bun.runtime-single-lockfile.convention.yaml +16 -6
- package/conventions/coder.bun/coder.bun.runtime-typecheck-enforced.convention.yaml +16 -9
- package/integrity.json +51 -50
- package/package.json +1 -1
- package/relationships.yaml +71 -0
- package/src/enforce.ts +2 -2
- package/src/profile-registry.ts +4 -2
- package/templates/agents/AGENTS.block.md +2 -0
|
@@ -20,7 +20,23 @@ content:
|
|
|
20
20
|
raw color literals in their values.
|
|
21
21
|
normative_text: A raw color is a theme decision made in one place. It does not follow dark mode, it drifts from
|
|
22
22
|
the palette, and nobody can find it when the palette changes.
|
|
23
|
-
fix_hint:
|
|
23
|
+
fix_hint: |
|
|
24
|
+
Canonical path:
|
|
25
|
+
* define the required color once in the tokens layer and reference that token from UI code.
|
|
26
|
+
|
|
27
|
+
During GREEN:
|
|
28
|
+
* reuse an existing semantic color token when it already expresses the required role,
|
|
29
|
+
* add the smallest new semantic token only when the current visual behavior needs a distinct value,
|
|
30
|
+
* change only the affected UI reference.
|
|
31
|
+
|
|
32
|
+
Do not broaden:
|
|
33
|
+
* do not retheme unrelated components,
|
|
34
|
+
* do not duplicate an existing token under a new name,
|
|
35
|
+
* do not use a raw literal as a temporary shortcut.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current visual or behavioral acceptance passes,
|
|
39
|
+
* affected UI files contain no raw color literal outside the tokens layer.
|
|
24
40
|
exceptions:
|
|
25
41
|
- Test files (`*.test.*`, `*.spec.*`) and vendored/build directories are never scanned.
|
|
26
42
|
- 'Custom property definitions (`--danger: #b91c1c`) define tokens wherever they live and are not flagged.'
|
|
@@ -20,8 +20,23 @@ content:
|
|
|
20
20
|
the design system's own primitives and components.
|
|
21
21
|
normative_text: Spacing and motion are the rhythm of an interface. Each hardcoded `13px` is a new step on a scale
|
|
22
22
|
nobody chose, and the rhythm erodes one component at a time.
|
|
23
|
-
fix_hint:
|
|
24
|
-
|
|
23
|
+
fix_hint: |
|
|
24
|
+
Canonical path:
|
|
25
|
+
* take spacing, inset, radius, and duration values from the existing foundations scale.
|
|
26
|
+
|
|
27
|
+
During GREEN:
|
|
28
|
+
* reuse the nearest existing semantic or scale token,
|
|
29
|
+
* add a new foundation value only when the current design genuinely requires a distinct value,
|
|
30
|
+
* change only the declaration needed by the acceptance.
|
|
31
|
+
|
|
32
|
+
Do not broaden:
|
|
33
|
+
* do not normalize unrelated styling,
|
|
34
|
+
* do not create one-off tokens that merely rename a hardcoded literal,
|
|
35
|
+
* do not bypass the scale for speed.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current visual or behavioral acceptance passes,
|
|
39
|
+
* affected UI values come from the declared foundations.
|
|
25
40
|
exceptions:
|
|
26
41
|
- Test files (`*.test.*`, `*.spec.*`) and vendored/build directories are never scanned.
|
|
27
42
|
- 0 and 1px (hairline borders) are not design decisions and are allowed.
|
|
@@ -18,8 +18,24 @@ content:
|
|
|
18
18
|
summary: Scans token/foundation code files for renderer imports, rendered markup, and control flow.
|
|
19
19
|
normative_text: Tokens are what every other layer depends on. Once they render or decide, the bottom of the hierarchy
|
|
20
20
|
has behaviour, and every primitive inherits it.
|
|
21
|
-
fix_hint:
|
|
22
|
-
|
|
21
|
+
fix_hint: |
|
|
22
|
+
Canonical path:
|
|
23
|
+
* keep tokens and foundations as values only,
|
|
24
|
+
* move markup to primitives/components and behavior to the layer that owns it.
|
|
25
|
+
|
|
26
|
+
During GREEN:
|
|
27
|
+
* leave the value in the token or foundation file,
|
|
28
|
+
* move only the markup or logic required by the current behavior to the nearest existing owning layer,
|
|
29
|
+
* reuse an existing primitive or component before creating a new one.
|
|
30
|
+
|
|
31
|
+
Do not broaden:
|
|
32
|
+
* do not reorganize unrelated tokens,
|
|
33
|
+
* do not move behavior into a different layer merely to silence the rule,
|
|
34
|
+
* do not create a generalized component unrelated to the current acceptance.
|
|
35
|
+
|
|
36
|
+
Prove:
|
|
37
|
+
* the current behavioral or rendering acceptance passes,
|
|
38
|
+
* token and foundation files remain value-only.
|
|
23
39
|
exceptions:
|
|
24
40
|
- Test files (`*.test.*`, `*.spec.*`) and vendored/build directories are never scanned.
|
|
25
41
|
- '`.css` token files are values by construction and are not scanned by this rule.'
|
|
@@ -17,8 +17,24 @@ content:
|
|
|
17
17
|
summary: Flags relative imports from a design-system file that leave the design root.
|
|
18
18
|
normative_text: 'A design system that reaches into a wagon has become part of that wagon: it cannot be reused
|
|
19
19
|
by the next one, and a change to the wagon breaks the system.'
|
|
20
|
-
fix_hint:
|
|
21
|
-
|
|
20
|
+
fix_hint: |
|
|
21
|
+
Canonical path:
|
|
22
|
+
* keep the design system independent of application and wagon code,
|
|
23
|
+
* pass app-specific values into design components or move genuinely shared, design-owned types/constants inward.
|
|
24
|
+
|
|
25
|
+
During GREEN:
|
|
26
|
+
* prefer props or existing design-system contracts for the current value,
|
|
27
|
+
* add only the smallest input surface required by the acceptance,
|
|
28
|
+
* move a type or constant only when it is truly owned by the design system.
|
|
29
|
+
|
|
30
|
+
Do not broaden:
|
|
31
|
+
* do not import a wagon through a barrel or alias,
|
|
32
|
+
* do not relocate app-specific concepts into design code just to make the import legal,
|
|
33
|
+
* do not generalize unrelated design APIs.
|
|
34
|
+
|
|
35
|
+
Prove:
|
|
36
|
+
* the current behavioral or rendering acceptance passes,
|
|
37
|
+
* design-system files import nothing from app or wagon code.
|
|
22
38
|
exceptions:
|
|
23
39
|
- Test files (`*.test.*`, `*.spec.*`) and vendored/build directories are never scanned.
|
|
24
40
|
- Bare package specifiers (`hono/jsx`) are outside the project graph and are not judged.
|
|
@@ -20,7 +20,22 @@ content:
|
|
|
20
20
|
normative_text: |
|
|
21
21
|
Mapping is translation across a boundary, which is precisely what the integration layer is for. A mapper in the domain drags the wire format inward; a mapper in presentation duplicates itself once a second caller appears.
|
|
22
22
|
fix_hint: |
|
|
23
|
-
|
|
23
|
+
Canonical path:
|
|
24
|
+
* keep DTO-to-domain and domain-to-DTO translation in the integration layer where both shapes are legitimately visible.
|
|
25
|
+
|
|
26
|
+
During GREEN:
|
|
27
|
+
* reuse an existing mapper for the same boundary when one exists,
|
|
28
|
+
* add only the field mapping required by the current acceptance,
|
|
29
|
+
* create a new mapper only for a genuinely new boundary translation.
|
|
30
|
+
|
|
31
|
+
Do not broaden:
|
|
32
|
+
* do not move domain behavior into the mapper,
|
|
33
|
+
* do not migrate unrelated mappings,
|
|
34
|
+
* do not place translation in presentation or domain as a shortcut.
|
|
35
|
+
|
|
36
|
+
Prove:
|
|
37
|
+
* the current behavioral acceptance passes,
|
|
38
|
+
* the mapper lives in integration and preserves the intended boundary.
|
|
24
39
|
exceptions:
|
|
25
40
|
- Test files and vendored/build directories are never scanned.
|
|
26
41
|
- Bare npm specifiers resolve outside the project graph and are not layer-checked.
|
|
@@ -21,7 +21,22 @@ content:
|
|
|
21
21
|
normative_text: |
|
|
22
22
|
A DTO belongs to the contract, not to either side of it. Declared inside one feature's layer it becomes that feature's private type that another feature imports anyway — and the boundary it was meant to define now runs through somebody's internals.
|
|
23
23
|
fix_hint: |
|
|
24
|
-
|
|
24
|
+
Canonical path:
|
|
25
|
+
* declare a DTO in `contracts/` and import that shared boundary shape from both sides.
|
|
26
|
+
|
|
27
|
+
During GREEN:
|
|
28
|
+
* reuse an existing contract type when it already represents the required payload,
|
|
29
|
+
* add only the fields required by the current acceptance,
|
|
30
|
+
* create a new DTO only when the behavior introduces a genuinely distinct boundary shape.
|
|
31
|
+
|
|
32
|
+
Do not broaden:
|
|
33
|
+
* do not move unrelated internal types into contracts,
|
|
34
|
+
* do not add speculative fields for future callers,
|
|
35
|
+
* do not declare the DTO inside a feature layer as a temporary shortcut.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current behavioral acceptance passes,
|
|
39
|
+
* every affected DTO declaration lives under `contracts/`.
|
|
25
40
|
exceptions:
|
|
26
41
|
- Test files and vendored/build directories are never scanned.
|
|
27
42
|
- Bare npm specifiers resolve outside the project graph and are not layer-checked.
|
|
@@ -22,7 +22,23 @@ content:
|
|
|
22
22
|
A DTO is the shape crossing a boundary. A method on it means behaviour crossed too, and the two sides are now coupled to an implementation rather than to data. A mutable field means the receiver can change what the sender said.
|
|
23
23
|
Both faults look harmless in one file and become impossible to unpick once a second consumer exists.
|
|
24
24
|
fix_hint: |
|
|
25
|
-
|
|
25
|
+
Canonical path:
|
|
26
|
+
* keep DTOs as immutable data: readonly fields and no methods,
|
|
27
|
+
* put behavior in the layer that consumes or produces the DTO.
|
|
28
|
+
|
|
29
|
+
During GREEN:
|
|
30
|
+
* add only the readonly data fields required by the current boundary behavior,
|
|
31
|
+
* reuse existing functions for transformation or behavior when available,
|
|
32
|
+
* add a small free function only when the current acceptance needs it.
|
|
33
|
+
|
|
34
|
+
Do not broaden:
|
|
35
|
+
* do not attach convenience methods to the DTO,
|
|
36
|
+
* do not make fields mutable to simplify implementation,
|
|
37
|
+
* do not introduce unrelated helpers or abstractions.
|
|
38
|
+
|
|
39
|
+
Prove:
|
|
40
|
+
* the current behavioral acceptance passes,
|
|
41
|
+
* the affected DTO remains pure immutable data.
|
|
26
42
|
exceptions:
|
|
27
43
|
- Test files and vendored/build directories are never scanned.
|
|
28
44
|
- Bare npm specifiers resolve outside the project graph and are not layer-checked.
|
|
@@ -26,8 +26,32 @@ content:
|
|
|
26
26
|
normative_text: |
|
|
27
27
|
Normalization is what makes the rule useful: because identifiers are folded, renaming a variable does not hide a duplicate, so the fingerprint tracks STRUCTURE rather than text.
|
|
28
28
|
The intra-layer restriction is equally deliberate. The same shape appearing in `domain/` and in `presentation/` is usually two different obligations that happen to look alike, and merging them couples layers that should move independently. Twice inside one layer is the shape that genuinely wanted extracting.
|
|
29
|
+
Treat a duplicate fingerprint as a sensor that two sites may share one responsibility or change reason. The goal is not to make the fingerprints differ; it is to decide whether the two fragments represent one concept that should be owned once or two concepts whose real semantic differences should remain independent.
|
|
29
30
|
fix_hint: |
|
|
30
|
-
|
|
31
|
+
Compare the duplicated sites semantically before extracting anything.
|
|
32
|
+
|
|
33
|
+
Diagnose:
|
|
34
|
+
* determine whether both fragments implement the same responsibility and should change for the same reason,
|
|
35
|
+
* identify the smallest stable behavior they genuinely share,
|
|
36
|
+
* check that the shared behavior belongs inside the same architectural layer.
|
|
37
|
+
|
|
38
|
+
Prefer:
|
|
39
|
+
* extract a focused function or module within that layer when both sites represent one concept,
|
|
40
|
+
* give the shared behavior a domain- or responsibility-revealing name,
|
|
41
|
+
* when the sites represent different responsibilities, preserve their independence and express any real semantic differences directly.
|
|
42
|
+
|
|
43
|
+
Avoid:
|
|
44
|
+
* renaming identifiers, changing literals, reordering harmless statements, or making other cosmetic edits solely to defeat normalization,
|
|
45
|
+
* creating a cross-layer abstraction just because two layers contain similar-shaped code,
|
|
46
|
+
* extracting a highly parameterized generic helper that obscures the two callers' intent,
|
|
47
|
+
* forcing distinct responsibilities into one abstraction merely to remove the finding.
|
|
48
|
+
|
|
49
|
+
Verify:
|
|
50
|
+
* existing behavior and tests remain green,
|
|
51
|
+
* the duplicate is removed because ownership became clearer or because genuine semantic differences are now explicit,
|
|
52
|
+
* dependency direction and layer boundaries remain valid,
|
|
53
|
+
* the extracted abstraction has one coherent reason to change,
|
|
54
|
+
* the refactor introduces no new ATDD Bun violations.
|
|
31
55
|
exceptions:
|
|
32
56
|
- Test, spec, and `.d.ts` files are excluded, as are `index.ts` barrels and `__tests__` directories.
|
|
33
57
|
- Trivial lines (bare braces, closing punctuation) are not counted toward the 7.
|
|
@@ -25,13 +25,21 @@ content:
|
|
|
25
25
|
The order is the same in Python, Vite and here, and its value is that a reader — human or tool — knows where to look without parsing. Identity first, then proof, then execution context, then intent: each field answers the question the previous one raises.
|
|
26
26
|
The rule judges only fields that are present, so it never double-reports a missing field that another rule already owns.
|
|
27
27
|
fix_hint: |
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
Canonical path:
|
|
29
|
+
* order present traceability fields as URN -> Tested-By -> Runtime -> Purpose.
|
|
30
|
+
|
|
31
|
+
During GREEN:
|
|
32
|
+
* keep the existing field values unless another convention proves one is wrong,
|
|
33
|
+
* reorder only the header lines needed to restore the canonical sequence,
|
|
34
|
+
* preserve unrelated comments.
|
|
35
|
+
|
|
36
|
+
Do not broaden:
|
|
37
|
+
* do not rewrite identifiers, acceptance bindings, runtime, or purpose merely while fixing order,
|
|
38
|
+
* do not move implementation code to satisfy a header-order finding.
|
|
39
|
+
|
|
40
|
+
Prove:
|
|
41
|
+
* the current behavioral acceptance still passes,
|
|
42
|
+
* the present header fields appear in canonical order.
|
|
35
43
|
exceptions:
|
|
36
44
|
- Files with no URN are skipped — there is nothing to order against.
|
|
37
45
|
- Fields that are absent are not considered; presence is each field's own rule.
|
|
@@ -21,11 +21,22 @@ content:
|
|
|
21
21
|
normative_text: |
|
|
22
22
|
The 80-character cap is the whole rule. An unbounded field becomes a paragraph, a paragraph goes stale, and a stale paragraph is worse than no description because it is believed. A single line that must fit forces the author to name the file's one job — and a file whose job will not fit in 80 characters is usually a file doing more than one thing, which makes this a design signal as much as a documentation rule.
|
|
23
23
|
fix_hint: |
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
Canonical path:
|
|
25
|
+
* state the file's one actual job in a single `Purpose:` line of at most 80 characters.
|
|
26
|
+
|
|
27
|
+
During GREEN:
|
|
28
|
+
* derive the purpose from the responsibility introduced for the current acceptance,
|
|
29
|
+
* use concrete responsibility language rather than implementation mechanics,
|
|
30
|
+
* if the purpose genuinely cannot fit because the new file owns multiple jobs, split only the responsibilities required by the current behavior.
|
|
31
|
+
|
|
32
|
+
Do not broaden:
|
|
33
|
+
* do not invent a vague purpose just to meet the length cap,
|
|
34
|
+
* do not perform unrelated decomposition,
|
|
35
|
+
* do not describe hypothetical future responsibilities.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current behavioral acceptance passes,
|
|
39
|
+
* the purpose truthfully names one job and fits the limit.
|
|
29
40
|
exceptions:
|
|
30
41
|
- Exactly 80 characters passes; 81 does not.
|
|
31
42
|
- A missing description is reported at the URN line.
|
|
@@ -22,12 +22,21 @@ content:
|
|
|
22
22
|
normative_text: |
|
|
23
23
|
`isomorphic` has no Vite counterpart and is the substantive addition. A bundler stack decides at BUILD time which code reaches the browser, so a file is server or client by where the bundler puts it. Bun decides at RUN time, and a full-stack Bun app routinely runs one module in both places — a fragment renderer used server-side and again after a client-side swap. Without a value for that, authors would be forced to pick a wrong one, and every downstream reader would inherit the error.
|
|
24
24
|
fix_hint: |
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
Canonical path:
|
|
26
|
+
* declare the runtime where the file actually executes: `bun`, `browser`, or `isomorphic`.
|
|
27
|
+
|
|
28
|
+
During GREEN:
|
|
29
|
+
* derive the value from the real execution path created or used by the current acceptance,
|
|
30
|
+
* keep an existing correct runtime declaration,
|
|
31
|
+
* change only the header when the implementation already executes in the correct place.
|
|
32
|
+
|
|
33
|
+
Do not broaden:
|
|
34
|
+
* do not move code between server and browser merely to fit a preferred label,
|
|
35
|
+
* do not guess `isomorphic` because the file could theoretically run in both places.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current behavioral acceptance passes in its real runtime,
|
|
39
|
+
* the declaration matches where the file actually executes.
|
|
31
40
|
exceptions:
|
|
32
41
|
- A missing declaration is reported at the URN line (or the first meaningful line when there is no URN).
|
|
33
42
|
- Test files are excluded.
|
|
@@ -23,17 +23,22 @@ content:
|
|
|
23
23
|
This is the rule that makes the whole header load-bearing rather than decorative. The URN says what the file IS; `Tested-By:` says what PROVES it. Together they close the loop from acceptance to implementation that ATDD exists to keep closed — which is exactly the loop that a stack migration breaks silently, because the new files are written without headers and nothing notices.
|
|
24
24
|
An empty block is treated as absent deliberately: it is the shape a half-finished backfill leaves behind, and accepting it would let a repo report full header coverage with zero acceptance bindings.
|
|
25
25
|
fix_hint: |
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
Canonical path:
|
|
27
|
+
* bind the implementation file to at least one real acceptance URN in its `Tested-By:` block.
|
|
28
|
+
|
|
29
|
+
During GREEN:
|
|
30
|
+
* derive the binding from the acceptance currently being implemented,
|
|
31
|
+
* keep existing valid bindings and add only the acceptance that genuinely covers this file,
|
|
32
|
+
* use the exact declared acceptance URN.
|
|
33
|
+
|
|
34
|
+
Do not broaden:
|
|
35
|
+
* do not invent acceptance IDs,
|
|
36
|
+
* do not add unrelated tests merely to make the block non-empty,
|
|
37
|
+
* do not claim coverage from an acceptance that does not exercise the implementation.
|
|
38
|
+
|
|
39
|
+
Prove:
|
|
40
|
+
* the named behavioral acceptance passes,
|
|
41
|
+
* the file's `Tested-By:` block names the acceptance that actually proves it.
|
|
37
42
|
exceptions:
|
|
38
43
|
- Test files are excluded — they are the other end of this binding.
|
|
39
44
|
- One entry satisfies the rule; more are encouraged.
|
|
@@ -21,10 +21,22 @@ content:
|
|
|
21
21
|
normative_text: |
|
|
22
22
|
The layer segment is what the boundary and dependency-flow rules read to decide whether an import is legal. A file declaring a layer outside the vocabulary is not merely mislabelled — it is unreachable by every layering rule, so it becomes a hole through which any dependency may pass unchallenged.
|
|
23
23
|
fix_hint: |
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
Canonical path:
|
|
25
|
+
* declare one of `domain`, `application`, `integration`, `presentation`, or `assembly` according to the file's real responsibility.
|
|
26
|
+
|
|
27
|
+
During GREEN:
|
|
28
|
+
* derive the layer from the existing architecture and the responsibility required by the current acceptance,
|
|
29
|
+
* follow the nearest existing compliant feature pattern,
|
|
30
|
+
* if the file is actually misplaced, move only the affected implementation to its proper layer.
|
|
31
|
+
|
|
32
|
+
Do not broaden:
|
|
33
|
+
* do not invent a new layer,
|
|
34
|
+
* do not relabel a misplaced module to make dependency checks disappear,
|
|
35
|
+
* do not reorganize adjacent features.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current behavioral acceptance passes,
|
|
39
|
+
* the URN layer matches the implementation's actual architectural layer.
|
|
28
40
|
exceptions:
|
|
29
41
|
- URNs that are not six segments are skipped.
|
|
30
42
|
- The vocabulary is fixed by core, not by this extension; a new layer is a core change.
|
|
@@ -28,15 +28,22 @@ content:
|
|
|
28
28
|
The URN is the only edge between a source file and the plan graph. Without it a file is invisible to traceability: no acceptance can claim it, no wagon owns it, and coverage reporting cannot see it exists.
|
|
29
29
|
"First meaningful line" excludes a shebang (`#!/usr/bin/env bun`) and an HTML doctype, because neither is content and neither should be able to displace the marker. The Vite sibling counts a shebang as the first non-empty line and so reports a header it actually has as missing; this realization does not.
|
|
30
30
|
fix_hint: |
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
Canonical path:
|
|
32
|
+
* put the component URN on the first meaningful line, after only an allowed shebang or HTML doctype.
|
|
33
|
+
|
|
34
|
+
During GREEN:
|
|
35
|
+
* derive the URN from the plan ownership of the implementation being added,
|
|
36
|
+
* use source-comment syntax for code and HTML-comment syntax for templates,
|
|
37
|
+
* add only the marker; do not restructure the file when the implementation is otherwise correctly placed.
|
|
38
|
+
|
|
39
|
+
Do not broaden:
|
|
40
|
+
* do not invent a wagon, feature, component, side, or layer,
|
|
41
|
+
* do not copy a nearby file's URN without verifying ownership,
|
|
42
|
+
* do not move code merely to make the marker easier to write.
|
|
43
|
+
|
|
44
|
+
Prove:
|
|
45
|
+
* the current behavioral acceptance passes,
|
|
46
|
+
* the file is traceable from its real component URN.
|
|
40
47
|
exceptions:
|
|
41
48
|
- Test files (`*.test.*`, `*.spec.*`) are excluded — they are bound by their acceptance URNs instead.
|
|
42
49
|
- Vendored and generated trees (`node_modules`, `dist`, `build`, `_generated`) are never scanned.
|
|
@@ -23,11 +23,22 @@ content:
|
|
|
23
23
|
A URN naming a different component than the file it sits in is worse than a missing one: it binds the file's evidence to somebody else's component, so both are wrong and neither is obviously wrong. This is the failure a copy-pasted header produces, which is how it usually arises.
|
|
24
24
|
The exempt set is the Vite set plus this stack's idioms — `server`, `routes`, `layout`, `partial`, `fragment`, `middleware` — because a full-stack Bun app's entrypoint is `server.ts` and its htmx fragments are named for their role, not for a component.
|
|
25
25
|
fix_hint: |
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
Canonical path:
|
|
27
|
+
* make the URN `{Name}` identify the component implemented by the file and match its basename under the rule's normalization, unless the file has an exempt structural role.
|
|
28
|
+
|
|
29
|
+
During GREEN:
|
|
30
|
+
* derive the name from the actual file/component being implemented,
|
|
31
|
+
* correct a copied or stale header before considering a file rename,
|
|
32
|
+
* keep structural-role filenames as structural roles when that is their real responsibility.
|
|
33
|
+
|
|
34
|
+
Do not broaden:
|
|
35
|
+
* do not rename a correctly named component merely to preserve a wrong URN,
|
|
36
|
+
* do not use an exempt structural name to evade component identity,
|
|
37
|
+
* do not change unrelated identity segments.
|
|
38
|
+
|
|
39
|
+
Prove:
|
|
40
|
+
* the current behavioral acceptance passes,
|
|
41
|
+
* the URN name and implementation identity agree.
|
|
31
42
|
exceptions:
|
|
32
43
|
- 'Structural names are exempt: composition, wagon, entrypoint, http, index, schema, router, routes, server, layout, partial, fragment, middleware.'
|
|
33
44
|
- Comparison ignores case and non-alphanumerics, so `order-row.ts` matches `OrderRow`.
|
|
@@ -24,10 +24,22 @@ content:
|
|
|
24
24
|
normative_text: |
|
|
25
25
|
Each segment is a join key. Wagon and feature locate the work item, name identifies the component, side and layer place it in the architecture. A URN missing a segment does not degrade gracefully — it resolves to nothing, and the file is as unbound as one with no marker at all, while LOOKING traceable in review.
|
|
26
26
|
fix_hint: |
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
Canonical path:
|
|
28
|
+
* use exactly `component:{wagon}:{feature}:{Name}:{side}:{layer}` with every segment present.
|
|
29
|
+
|
|
30
|
+
During GREEN:
|
|
31
|
+
* derive each segment from the plan, filename, execution side, and architectural responsibility,
|
|
32
|
+
* fix only the malformed or missing segment,
|
|
33
|
+
* keep already-correct identity segments unchanged.
|
|
34
|
+
|
|
35
|
+
Do not broaden:
|
|
36
|
+
* do not invent placeholder segments,
|
|
37
|
+
* do not rename implementation artifacts solely to make a guessed URN fit,
|
|
38
|
+
* do not alter plan ownership while fixing URN grammar.
|
|
39
|
+
|
|
40
|
+
Prove:
|
|
41
|
+
* the current behavioral acceptance passes,
|
|
42
|
+
* the URN has the canonical six-segment shape.
|
|
31
43
|
exceptions:
|
|
32
44
|
- A file with no `URN:` marker is skipped (owned by `green-urn-marker`).
|
|
33
45
|
- Segment CONTENT is validated by the wagon-feature, name, side and layer rules; this rule checks shape only.
|
|
@@ -20,12 +20,21 @@ content:
|
|
|
20
20
|
normative_text: |
|
|
21
21
|
The vocabulary is unchanged from the Python and Vite realizations, and it matters MORE in a full-stack Bun app than in either. A Vite repo is frontend by construction and a python-pytest service is backend by construction, so the segment is close to redundant there. Here one repo, one language and one runtime span both halves, and the only thing that says which side a module belongs to is this segment — so it must be declared per file and cannot be inferred from the stack.
|
|
22
22
|
fix_hint: |
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
Canonical path:
|
|
24
|
+
* declare `frontend` for browser-owned implementation and `backend` for server-owned implementation.
|
|
25
|
+
|
|
26
|
+
During GREEN:
|
|
27
|
+
* derive side from where responsibility lives, not merely from file syntax,
|
|
28
|
+
* treat server-rendered htmx fragments as backend and browser-resident behavior as frontend,
|
|
29
|
+
* change only the side segment when the rest of the URN is correct.
|
|
30
|
+
|
|
31
|
+
Do not broaden:
|
|
32
|
+
* do not move implementation between client and server just to fix a header,
|
|
33
|
+
* do not use `Runtime:` as a substitute for the side decision.
|
|
34
|
+
|
|
35
|
+
Prove:
|
|
36
|
+
* the current behavioral acceptance passes,
|
|
37
|
+
* the side segment matches the implementation's real ownership.
|
|
29
38
|
exceptions:
|
|
30
39
|
- URNs that are not six segments are skipped.
|
|
31
40
|
- "`Runtime:` is a different axis — a `backend` file may declare `Runtime: isomorphic`."
|
|
@@ -22,12 +22,21 @@ content:
|
|
|
22
22
|
normative_text: |
|
|
23
23
|
Wagon and feature are join keys into `plan/`, and a join key that is case- or separator-sensitive fails silently: `Orders` and `orders` are two different wagons to a string match, so a header with the wrong casing binds to nothing while reading correctly to a human. Kebab-case is the plan's own grammar, so the header must use it exactly.
|
|
24
24
|
fix_hint: |
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
Canonical path:
|
|
26
|
+
* use the exact plan wagon and feature identifiers in lowercase kebab-case.
|
|
27
|
+
|
|
28
|
+
During GREEN:
|
|
29
|
+
* derive both values from the feature currently being implemented,
|
|
30
|
+
* normalize only casing or separators when the identity is already correct,
|
|
31
|
+
* keep the component name, side, and layer untouched.
|
|
32
|
+
|
|
33
|
+
Do not broaden:
|
|
34
|
+
* do not invent or rename plan wagons/features to satisfy the source header,
|
|
35
|
+
* do not copy identifiers from a neighboring feature without checking ownership.
|
|
36
|
+
|
|
37
|
+
Prove:
|
|
38
|
+
* the current behavioral acceptance passes,
|
|
39
|
+
* wagon and feature segments match the plan's canonical identifiers.
|
|
31
40
|
exceptions:
|
|
32
41
|
- URNs that are not six well-formed segments are skipped (owned by `green-urn-pattern`).
|
|
33
42
|
- The name, side and layer segments are governed by their own rules.
|
|
@@ -23,7 +23,22 @@ content:
|
|
|
23
23
|
ADDED TO THE MIRROR, and worth flagging: the Convex sibling accepts only the FILENAME form, because its function tree is flat. A full-stack Bun repo commonly nests (`features/orders/domain/total.ts`), so accepting only filenames would refuse the idiomatic layout. This realization accepts BOTH.
|
|
24
24
|
The obligation is unchanged: a reader should know a file's role before opening it, and the layering rules need something to read.
|
|
25
25
|
fix_hint: |
|
|
26
|
-
|
|
26
|
+
Canonical path:
|
|
27
|
+
* place the module in the architectural layer that owns its responsibility, or name the file with that layer when the repository uses the filename form.
|
|
28
|
+
|
|
29
|
+
During GREEN:
|
|
30
|
+
* derive the layer from the responsibility the current behavior actually implements,
|
|
31
|
+
* follow the nearest existing feature layout,
|
|
32
|
+
* move or rename only the affected module when placement is wrong.
|
|
33
|
+
|
|
34
|
+
Do not broaden:
|
|
35
|
+
* do not reorganize sibling features,
|
|
36
|
+
* do not invent a new layer name,
|
|
37
|
+
* do not choose a layer merely to make another import rule pass.
|
|
38
|
+
|
|
39
|
+
Prove:
|
|
40
|
+
* the current behavioral acceptance passes,
|
|
41
|
+
* the file's declared location or name matches its actual architectural responsibility.
|
|
27
42
|
exceptions:
|
|
28
43
|
- Test files and vendored/build directories are never scanned.
|
|
29
44
|
- Bare npm specifiers resolve outside the project graph and are not layer-checked.
|