@afokapu/atdd-bun 0.10.104 → 0.10.106
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/README.md +13 -0
- package/conventions/_profiles/planner.yaml +150 -0
- package/conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml +1 -1
- package/detectors/bun_ts_metrics_detector/checks/ts_duplication.mjs +2 -0
- package/integrity.json +18 -10
- package/package.json +1 -1
- package/planner-nodes/ENFORCEMENT_SCOPE.yaml +5 -5
- package/planner-nodes/nodes/planner.journey.execution-strategies.convention.yaml +27 -0
- package/planner-nodes/nodes/planner.journey.strategy.adaptive.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.batched.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.cached.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.concurrent.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.conditional.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.pipelined.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.reference.convention.yaml +28 -0
- package/planner-nodes/nodes/planner.journey.strategy.speculative.convention.yaml +28 -0
- package/relationships.yaml +100 -1
- package/src/enforce.ts +12 -1
- package/src/hooks.ts +42 -15
- package/PLANNER_PORT.md +0 -55
package/README.md
CHANGED
|
@@ -73,6 +73,19 @@ registerEnforcementTest({ root: import.meta.dir + "/..", profiles: ["traceabilit
|
|
|
73
73
|
|
|
74
74
|
`planner-nodes/ENFORCEMENT_SCOPE.yaml` says which canonical planner rules have a Bun realization.
|
|
75
75
|
|
|
76
|
+
### Journey execution strategy conventions
|
|
77
|
+
|
|
78
|
+
The planner profile exposes Bun-owned `planner.journey.execution-strategies` and eight individual
|
|
79
|
+
strategy patterns: reference, conditional, concurrent, pipelined, batched, cached, speculative,
|
|
80
|
+
and adaptive. Each describes applicability, constraints, evidence, and its actual runtime
|
|
81
|
+
support. Agents discover them through the generated planner profile registry. Strategies
|
|
82
|
+
can combine, but none is mandatory or a runtime mode merely because the convention exists.
|
|
83
|
+
|
|
84
|
+
Existing journey continuation, interlocking route, and acceptance validators remain strict.
|
|
85
|
+
Convention guidance does **not** enable undeclared fork/join, streaming, or speculative
|
|
86
|
+
execution: these require their own runtime semantics and acceptance evidence.
|
|
87
|
+
|
|
88
|
+
|
|
76
89
|
## Greenfield and brownfield
|
|
77
90
|
|
|
78
91
|
A greenfield repository enforces every profile from the start: that is the default. A brownfield
|
|
@@ -42,8 +42,28 @@ conventions:
|
|
|
42
42
|
path: "planner-nodes/nodes/planner.feature.wagon-link.convention.yaml"
|
|
43
43
|
- rule_id: "planner.journey.continuation-closure"
|
|
44
44
|
path: "planner-nodes/nodes/planner.journey.continuation-closure.convention.yaml"
|
|
45
|
+
- rule_id: "planner.journey.definition"
|
|
46
|
+
path: "planner-nodes/nodes/planner.journey.definition.convention.yaml"
|
|
47
|
+
- rule_id: "planner.journey.execution-strategies"
|
|
48
|
+
path: "planner-nodes/nodes/planner.journey.execution-strategies.convention.yaml"
|
|
45
49
|
- rule_id: "planner.journey.interlocking-composed"
|
|
46
50
|
path: "planner-nodes/nodes/planner.journey.interlocking-composed.convention.yaml"
|
|
51
|
+
- rule_id: "planner.journey.strategy.adaptive"
|
|
52
|
+
path: "planner-nodes/nodes/planner.journey.strategy.adaptive.convention.yaml"
|
|
53
|
+
- rule_id: "planner.journey.strategy.batched"
|
|
54
|
+
path: "planner-nodes/nodes/planner.journey.strategy.batched.convention.yaml"
|
|
55
|
+
- rule_id: "planner.journey.strategy.cached"
|
|
56
|
+
path: "planner-nodes/nodes/planner.journey.strategy.cached.convention.yaml"
|
|
57
|
+
- rule_id: "planner.journey.strategy.concurrent"
|
|
58
|
+
path: "planner-nodes/nodes/planner.journey.strategy.concurrent.convention.yaml"
|
|
59
|
+
- rule_id: "planner.journey.strategy.conditional"
|
|
60
|
+
path: "planner-nodes/nodes/planner.journey.strategy.conditional.convention.yaml"
|
|
61
|
+
- rule_id: "planner.journey.strategy.pipelined"
|
|
62
|
+
path: "planner-nodes/nodes/planner.journey.strategy.pipelined.convention.yaml"
|
|
63
|
+
- rule_id: "planner.journey.strategy.reference"
|
|
64
|
+
path: "planner-nodes/nodes/planner.journey.strategy.reference.convention.yaml"
|
|
65
|
+
- rule_id: "planner.journey.strategy.speculative"
|
|
66
|
+
path: "planner-nodes/nodes/planner.journey.strategy.speculative.convention.yaml"
|
|
47
67
|
- rule_id: "planner.theme.must-be-canonical"
|
|
48
68
|
path: "planner-nodes/nodes/planner.theme.must-be-canonical.convention.yaml"
|
|
49
69
|
- rule_id: "planner.theme.theme-zero-mandatory"
|
|
@@ -277,6 +297,16 @@ relationships:
|
|
|
277
297
|
strength: "important"
|
|
278
298
|
target_ref: "tester.bun.acceptance-binding-declared"
|
|
279
299
|
type: "runs_alongside"
|
|
300
|
+
- confidence: 1
|
|
301
|
+
constraint: "mandatory"
|
|
302
|
+
control: "internal"
|
|
303
|
+
foundation: "finish_to_start"
|
|
304
|
+
origin: "@afokapu/atdd-bun"
|
|
305
|
+
reason: "JourneyRunner executes the continuation topology the plan declares; without a declared journey there is nothing for it to compose"
|
|
306
|
+
source_ref: "coder.bun.journey-runner-boundary"
|
|
307
|
+
strength: "critical"
|
|
308
|
+
target_ref: "planner.journey.definition"
|
|
309
|
+
type: "requires"
|
|
280
310
|
- confidence: 1
|
|
281
311
|
constraint: "discretionary"
|
|
282
312
|
control: "external"
|
|
@@ -337,6 +367,26 @@ relationships:
|
|
|
337
367
|
strength: "important"
|
|
338
368
|
target_ref: "planner.wagon.features"
|
|
339
369
|
type: "requires"
|
|
370
|
+
- confidence: 1
|
|
371
|
+
constraint: "mandatory"
|
|
372
|
+
control: "internal"
|
|
373
|
+
foundation: "finish_to_start"
|
|
374
|
+
origin: "@afokapu/atdd-bun"
|
|
375
|
+
reason: "decoding the nominal and sibling trains supplies what a journey composes across interlockings"
|
|
376
|
+
source_ref: "planner.decomposition.train-journey"
|
|
377
|
+
strength: "important"
|
|
378
|
+
target_ref: "planner.journey.definition"
|
|
379
|
+
type: "enables"
|
|
380
|
+
- confidence: 1
|
|
381
|
+
constraint: "mandatory"
|
|
382
|
+
control: "internal"
|
|
383
|
+
foundation: "finish_to_start"
|
|
384
|
+
origin: "@afokapu/atdd-bun"
|
|
385
|
+
reason: "the journey view is rendered from the journey topology the plan declares"
|
|
386
|
+
source_ref: "planner.docs.journey-view-current"
|
|
387
|
+
strength: "critical"
|
|
388
|
+
target_ref: "planner.journey.definition"
|
|
389
|
+
type: "requires"
|
|
340
390
|
- confidence: 1
|
|
341
391
|
constraint: "mandatory"
|
|
342
392
|
control: "internal"
|
|
@@ -377,6 +427,16 @@ relationships:
|
|
|
377
427
|
strength: "critical"
|
|
378
428
|
target_ref: "planner.journey.definition"
|
|
379
429
|
type: "requires"
|
|
430
|
+
- confidence: 1
|
|
431
|
+
constraint: "mandatory"
|
|
432
|
+
control: "internal"
|
|
433
|
+
foundation: "finish_to_start"
|
|
434
|
+
origin: "@afokapu/atdd-bun"
|
|
435
|
+
reason: "execution strategies inherit the existing journey ownership and continuation contract"
|
|
436
|
+
source_ref: "planner.journey.execution-strategies"
|
|
437
|
+
strength: "important"
|
|
438
|
+
target_ref: "planner.journey.definition"
|
|
439
|
+
type: "requires"
|
|
380
440
|
- confidence: 1
|
|
381
441
|
constraint: "mandatory"
|
|
382
442
|
control: "internal"
|
|
@@ -397,6 +457,86 @@ relationships:
|
|
|
397
457
|
strength: "critical"
|
|
398
458
|
target_ref: "planner.journey.definition"
|
|
399
459
|
type: "requires"
|
|
460
|
+
- confidence: 1
|
|
461
|
+
constraint: "mandatory"
|
|
462
|
+
control: "internal"
|
|
463
|
+
foundation: "finish_to_start"
|
|
464
|
+
origin: "@afokapu/atdd-bun"
|
|
465
|
+
reason: "the adaptive strategy requires the shared applicability and evidence principles"
|
|
466
|
+
source_ref: "planner.journey.strategy.adaptive"
|
|
467
|
+
strength: "important"
|
|
468
|
+
target_ref: "planner.journey.execution-strategies"
|
|
469
|
+
type: "requires"
|
|
470
|
+
- confidence: 1
|
|
471
|
+
constraint: "mandatory"
|
|
472
|
+
control: "internal"
|
|
473
|
+
foundation: "finish_to_start"
|
|
474
|
+
origin: "@afokapu/atdd-bun"
|
|
475
|
+
reason: "the batched strategy requires the shared applicability and evidence principles"
|
|
476
|
+
source_ref: "planner.journey.strategy.batched"
|
|
477
|
+
strength: "important"
|
|
478
|
+
target_ref: "planner.journey.execution-strategies"
|
|
479
|
+
type: "requires"
|
|
480
|
+
- confidence: 1
|
|
481
|
+
constraint: "mandatory"
|
|
482
|
+
control: "internal"
|
|
483
|
+
foundation: "finish_to_start"
|
|
484
|
+
origin: "@afokapu/atdd-bun"
|
|
485
|
+
reason: "the cached strategy requires the shared applicability and evidence principles"
|
|
486
|
+
source_ref: "planner.journey.strategy.cached"
|
|
487
|
+
strength: "important"
|
|
488
|
+
target_ref: "planner.journey.execution-strategies"
|
|
489
|
+
type: "requires"
|
|
490
|
+
- confidence: 1
|
|
491
|
+
constraint: "mandatory"
|
|
492
|
+
control: "internal"
|
|
493
|
+
foundation: "finish_to_start"
|
|
494
|
+
origin: "@afokapu/atdd-bun"
|
|
495
|
+
reason: "the concurrent strategy requires the shared applicability and evidence principles"
|
|
496
|
+
source_ref: "planner.journey.strategy.concurrent"
|
|
497
|
+
strength: "important"
|
|
498
|
+
target_ref: "planner.journey.execution-strategies"
|
|
499
|
+
type: "requires"
|
|
500
|
+
- confidence: 1
|
|
501
|
+
constraint: "mandatory"
|
|
502
|
+
control: "internal"
|
|
503
|
+
foundation: "finish_to_start"
|
|
504
|
+
origin: "@afokapu/atdd-bun"
|
|
505
|
+
reason: "the conditional strategy requires the shared applicability and evidence principles"
|
|
506
|
+
source_ref: "planner.journey.strategy.conditional"
|
|
507
|
+
strength: "important"
|
|
508
|
+
target_ref: "planner.journey.execution-strategies"
|
|
509
|
+
type: "requires"
|
|
510
|
+
- confidence: 1
|
|
511
|
+
constraint: "mandatory"
|
|
512
|
+
control: "internal"
|
|
513
|
+
foundation: "finish_to_start"
|
|
514
|
+
origin: "@afokapu/atdd-bun"
|
|
515
|
+
reason: "the pipelined strategy requires the shared applicability and evidence principles"
|
|
516
|
+
source_ref: "planner.journey.strategy.pipelined"
|
|
517
|
+
strength: "important"
|
|
518
|
+
target_ref: "planner.journey.execution-strategies"
|
|
519
|
+
type: "requires"
|
|
520
|
+
- confidence: 1
|
|
521
|
+
constraint: "mandatory"
|
|
522
|
+
control: "internal"
|
|
523
|
+
foundation: "finish_to_start"
|
|
524
|
+
origin: "@afokapu/atdd-bun"
|
|
525
|
+
reason: "the reference strategy requires the shared applicability and evidence principles"
|
|
526
|
+
source_ref: "planner.journey.strategy.reference"
|
|
527
|
+
strength: "important"
|
|
528
|
+
target_ref: "planner.journey.execution-strategies"
|
|
529
|
+
type: "requires"
|
|
530
|
+
- confidence: 1
|
|
531
|
+
constraint: "mandatory"
|
|
532
|
+
control: "internal"
|
|
533
|
+
foundation: "finish_to_start"
|
|
534
|
+
origin: "@afokapu/atdd-bun"
|
|
535
|
+
reason: "the speculative strategy requires the shared applicability and evidence principles"
|
|
536
|
+
source_ref: "planner.journey.strategy.speculative"
|
|
537
|
+
strength: "important"
|
|
538
|
+
target_ref: "planner.journey.execution-strategies"
|
|
539
|
+
type: "requires"
|
|
400
540
|
- confidence: 1
|
|
401
541
|
constraint: "mandatory"
|
|
402
542
|
control: "internal"
|
|
@@ -787,3 +927,13 @@ relationships:
|
|
|
787
927
|
strength: "important"
|
|
788
928
|
target_ref: "planner.wagon.urn-naming"
|
|
789
929
|
type: "requires"
|
|
930
|
+
- confidence: 1
|
|
931
|
+
constraint: "mandatory"
|
|
932
|
+
control: "internal"
|
|
933
|
+
foundation: "finish_to_start"
|
|
934
|
+
origin: "@afokapu/atdd-bun"
|
|
935
|
+
reason: "exposed journeys are the ones a journey declares with an exposed entrypoint"
|
|
936
|
+
source_ref: "tester.htmx.exposed-journey-e2e-coverage"
|
|
937
|
+
strength: "critical"
|
|
938
|
+
target_ref: "planner.journey.definition"
|
|
939
|
+
type: "requires"
|
|
@@ -57,7 +57,7 @@ content:
|
|
|
57
57
|
- Trivial lines (bare braces, closing punctuation) are not counted toward the 7.
|
|
58
58
|
- Import and re-export declarations are not counted, because two files importing the same names from one shared module match because the logic was shared, which is the fix this rule asks for.
|
|
59
59
|
- Property signatures inside a `type X = {` or `interface X {` body (optional `readonly`, a name, optional `?`, `:` a type, ending `;` or `,`), including the members of nested object types, are not counted, because two unrelated records with the same number of same-typed fields match once identifiers are folded and neither coupling them nor a cosmetic edit is a fix. Executable statements, object literals, class fields, enum bodies, and method bodies still count.
|
|
60
|
-
- Files whose layer cannot be determined are compared
|
|
60
|
+
- Files whose layer cannot be determined are not judged, because with no established layer there is no intra-layer comparison and unclassified paths are never compared with each other.
|
|
61
61
|
metadata:
|
|
62
62
|
aliases:
|
|
63
63
|
# DUPLICATION-TS-001 is the SHARED core alias, also carried by the agnostic node and by
|
|
@@ -30,6 +30,8 @@ for (const root of readRoots()) {
|
|
|
30
30
|
for (const f of walk(root, excludes, M.TS_EXT, true)) {
|
|
31
31
|
if (isExcluded(f)) continue;
|
|
32
32
|
const layer = M.determineLayer(f);
|
|
33
|
+
// A path with no established layer has no "same layer" to be duplicated within.
|
|
34
|
+
if (layer === "unknown") continue;
|
|
33
35
|
if (!byLayer.has(layer)) byLayer.set(layer, []);
|
|
34
36
|
byLayer.get(layer).push(f);
|
|
35
37
|
}
|
package/integrity.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
2
|
+
"version": "0.10.106",
|
|
3
3
|
"files": {
|
|
4
4
|
"HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
|
|
5
|
-
"
|
|
6
|
-
"README.md": "8f0e45595fc10bb6f033b81b67246e57bb3f5bbaf62b35ba950beb5f9f82a938",
|
|
5
|
+
"README.md": "8aefceaa24bee498f39081b2aaf4c0d5c54bc1ed9849c20e1d98d1427df56eab",
|
|
7
6
|
"bunfig.toml": "b9fc65eca9014c5179380259d70e76385a6a80788fa9a2df5fb3eaa5554fd2fe",
|
|
8
7
|
"conventions/_profiles/architecture.yaml": "f1808768b720a4e476047e4a0912002ca673946562cea9aeef5d0c214828d93a",
|
|
9
8
|
"conventions/_profiles/coder.yaml": "53693363c6623b5b12ece1c746c8cf4f052615310fc5683160d8de8be7d8e0c9",
|
|
@@ -13,7 +12,7 @@
|
|
|
13
12
|
"conventions/_profiles/htmx.yaml": "38fc8b3e1a53429e16977ed63e83e751b203deffe9b338ea171050fb64641559",
|
|
14
13
|
"conventions/_profiles/interlocking.yaml": "46a2a4fb2eb537941c991ef4178d009a30d14f84279e525ca0d0887d3239047d",
|
|
15
14
|
"conventions/_profiles/metrics.yaml": "82081754271e0cb08a1245ad658578907c8e0e455912aa954502334a82d7b4d3",
|
|
16
|
-
"conventions/_profiles/planner.yaml": "
|
|
15
|
+
"conventions/_profiles/planner.yaml": "f53311e9990881792a5fce07ffbcd9e8b1cc36c5cb82e4e8523f65dcbaef0878",
|
|
17
16
|
"conventions/_profiles/runtime.yaml": "48fae0d31fb9228b8819243c264721037720acb1763bf27f74325c14ffef46d4",
|
|
18
17
|
"conventions/_profiles/security.yaml": "38eb6b17e35e1439fe4f19c8ccf3ba1b2f18759a984dd1d33171ec3a29128876",
|
|
19
18
|
"conventions/_profiles/telemetry.yaml": "4c07c693357fad420df0df82a3ad196cd159df017fec6b98244841530516dfd9",
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"conventions/coder.bun/coder.bun.dto-mapper.convention.yaml": "c524b5f37db6ae4f7558fc3ec672aa1c5b764738a0f25a20062d736fed6bbcb3",
|
|
60
59
|
"conventions/coder.bun/coder.bun.dto-placement.convention.yaml": "9525255f9e037ca0d939de20e70235fe348dcebf2136536055bc21433d7e9fb5",
|
|
61
60
|
"conventions/coder.bun/coder.bun.dto-purity.convention.yaml": "4743199fb242a25f896425916e3873c2e8cf62f4285437f62b0f8f8139d6a58d",
|
|
62
|
-
"conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "
|
|
61
|
+
"conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "c3de56dbe9bef4d199abfceb2cf9b702a54b2683d437305466ca15b009cf3067",
|
|
63
62
|
"conventions/coder.bun/coder.bun.error-response-bare-string.convention.yaml": "c2c0f859f6dd12702edf225c4148849e72b6c25e6d7cd28edd5d644ba277a23c",
|
|
64
63
|
"conventions/coder.bun/coder.bun.error-response-code-format.convention.yaml": "3048fed00b92c2559f7c52f73cfcce07b583eb47b12d04f0851e237ae3646567",
|
|
65
64
|
"conventions/coder.bun/coder.bun.green-header-order.convention.yaml": "2a42d67bedeec1de76fa1de844351983c5ba4bc5b61d5a5047298f6804664f67",
|
|
@@ -718,7 +717,7 @@
|
|
|
718
717
|
"detectors/bun_ts_metrics_detector/checks/ts_complexity_length.mjs": "e49fe93dbf2c52a91fe97b1e0b810d60f7d34d43581dfb96d4827640e6f5e3fd",
|
|
719
718
|
"detectors/bun_ts_metrics_detector/checks/ts_complexity_nesting.mjs": "8d8f61ea1748f33b037beb3f3fe5c84acbce395575e24fb1d01432813762e4d1",
|
|
720
719
|
"detectors/bun_ts_metrics_detector/checks/ts_dead_code.mjs": "8f2205274f5056993a888ea4141be4d0b64c287e4641d0a464d178530b5297d4",
|
|
721
|
-
"detectors/bun_ts_metrics_detector/checks/ts_duplication.mjs": "
|
|
720
|
+
"detectors/bun_ts_metrics_detector/checks/ts_duplication.mjs": "4c34fe8494a492e4cbaf5c946a272485e0f01b1f8c638d1f442e13ad5b05b3d4",
|
|
722
721
|
"detectors/bun_ts_metrics_detector/checks/ts_quality_comments.mjs": "872d71d2165eba4cb39c975b09365cf67a64f1db5c55c0df9e86ff411e02ea31",
|
|
723
722
|
"detectors/bun_ts_metrics_detector/checks/ts_quality_mi.mjs": "69765d88441e98f4f38b7da0a416b7dab8b7f0072e562ea9d40d399802452067",
|
|
724
723
|
"detectors/bun_ts_metrics_detector/detect.mjs": "a3eef9ad7b18a5743e508f5ac8c54cdf601cead679ed832629bfd4936d2ce6df",
|
|
@@ -1036,7 +1035,7 @@
|
|
|
1036
1035
|
"lib/interlocking.mjs": "d0803d080ac7d7477c51be70112df1e85213d339fd3c6b71f75f26145fa8accd",
|
|
1037
1036
|
"lib/journey-chain.mjs": "34b1efa073b17940fa398af2970c85bb2fac35e4b2608ce635cfb6c39e3adc53",
|
|
1038
1037
|
"lib/scan.mjs": "b6973e411ecd14c548a055c871e01e948f002b772042136be8401f38d998e687",
|
|
1039
|
-
"planner-nodes/ENFORCEMENT_SCOPE.yaml": "
|
|
1038
|
+
"planner-nodes/ENFORCEMENT_SCOPE.yaml": "47aa9c78a4bb1754c6b435f5e056038baa04a24cd48df2c205db2bc08a3a3cac",
|
|
1040
1039
|
"planner-nodes/nodes/planner.acceptance.abstract-fields-required.convention.yaml": "bd565693f0ae861f0561ad2f7a91a8c55f9a209c3acd59c5750cfcffd96a85d8",
|
|
1041
1040
|
"planner-nodes/nodes/planner.acceptance.authoring-guidelines.convention.yaml": "16348dceed5868041b832bde766e9c8d4a950d4032f1f3066b357644081a3b17",
|
|
1042
1041
|
"planner-nodes/nodes/planner.acceptance.boundary-kind-vocabulary.convention.yaml": "c5645225399568c2d4fe632442f9c597b2c59e4f4239880df7db2cbdc0353c9c",
|
|
@@ -1143,7 +1142,16 @@
|
|
|
1143
1142
|
"planner-nodes/nodes/planner.issue-body.graph-context-required.convention.yaml": "6292ab37efda9fbdd1e028283bed7c594baa4e070266795180a3bcded2760621",
|
|
1144
1143
|
"planner-nodes/nodes/planner.journey.continuation-closure.convention.yaml": "56c447b05cfe98804ea53bdde68ad940138093a4341620872e9b5c61be08869c",
|
|
1145
1144
|
"planner-nodes/nodes/planner.journey.definition.convention.yaml": "a163bb9d5140d17a0dac996d84a8efc9f833592407dbebaec94db25006e88e28",
|
|
1145
|
+
"planner-nodes/nodes/planner.journey.execution-strategies.convention.yaml": "639f035af31ba3daabd79c59dfaa338ab7179ff9f89691f2b7c8a485bd1adecc",
|
|
1146
1146
|
"planner-nodes/nodes/planner.journey.interlocking-composed.convention.yaml": "91d3f1a9061a1fccaeeb52a07f1459f93f665d310dc453fecbd5db23c603a7ec",
|
|
1147
|
+
"planner-nodes/nodes/planner.journey.strategy.adaptive.convention.yaml": "59d97a125d6a9ce8b470b0614a950008438d63fe31c9ea53d251c282ba75a779",
|
|
1148
|
+
"planner-nodes/nodes/planner.journey.strategy.batched.convention.yaml": "e8eec802f9eec2b075a92f965e1d8850bb39093ac03c355230ed839d0b8d513a",
|
|
1149
|
+
"planner-nodes/nodes/planner.journey.strategy.cached.convention.yaml": "cabd71aa928248f4e27150f8598db69da7c7d5800f96f21ee0b6ec449ba7dac7",
|
|
1150
|
+
"planner-nodes/nodes/planner.journey.strategy.concurrent.convention.yaml": "1e761656f17ef6a33e827fc670dbadf766cacd705c994b239771dc465a6620c5",
|
|
1151
|
+
"planner-nodes/nodes/planner.journey.strategy.conditional.convention.yaml": "ed3d075ece7b26f79ca31f00279ca82db604b81653a4b3da1b7a67190c353a7d",
|
|
1152
|
+
"planner-nodes/nodes/planner.journey.strategy.pipelined.convention.yaml": "c13e8d0c5a9ed82f245d97fd097c6fbef21ecf7982657d63e219a1a2e3c939a4",
|
|
1153
|
+
"planner-nodes/nodes/planner.journey.strategy.reference.convention.yaml": "52e5db6b87e9800f7891208a66bb553c222fb465c95f219ab1918adc3dcc8298",
|
|
1154
|
+
"planner-nodes/nodes/planner.journey.strategy.speculative.convention.yaml": "6c925be358e9faf0858faca7477ff64361ec81aa66b28b608b1dc6acad504d22",
|
|
1147
1155
|
"planner-nodes/nodes/planner.plan.confirm-before-author.convention.yaml": "23116f68ce81ff78ab57d362cf7195c4bf637781d74df4aece4d61eafbf0a49b",
|
|
1148
1156
|
"planner-nodes/nodes/planner.plan.confirm-binds-an-issue.convention.yaml": "27de0e84fb7181a6768c65c30865fecdf94a3beddc3a47a4d6de226aaf014767",
|
|
1149
1157
|
"planner-nodes/nodes/planner.plan.confirm-requires-interlocking-sanity.convention.yaml": "7ae7d9c6c70d0f4d3e50ae81f1d9f18ee1f70f348bee33147ee99d2d3d4a4de4",
|
|
@@ -1255,13 +1263,13 @@
|
|
|
1255
1263
|
"planner-schemas/train.schema.json": "d6fbac9067c1bffeb84eb79a71228441055af6e6e7ba141dd4e0bcb079345ec0",
|
|
1256
1264
|
"planner-schemas/wagon.schema.json": "12353e46d2216d2deef754615b629a696bd8a7bb35326379e7ef2b221a5ece3a",
|
|
1257
1265
|
"planner-schemas/wmbt.schema.json": "7a3a5693bfcf01340667c2be4a3c48e74f34b1af7e8dc13372c0de06b7f4fe12",
|
|
1258
|
-
"relationships.yaml": "
|
|
1266
|
+
"relationships.yaml": "af7b9d56fd52e00b10845ac4c5bcbec77a44338c0aaa29b548aa7fa53eba4c59",
|
|
1259
1267
|
"src/agent.ts": "6d6c6e75908af8fbab13432f0001b0374bb25cf3dee46ba218dfd67e0090cb56",
|
|
1260
1268
|
"src/ci.ts": "b5c57dd87fc780b2b272156b68830d14e695a1a28300dec46a06f71864e0c59e",
|
|
1261
1269
|
"src/cli.ts": "395638ab87565bb10c2beb35988ff1acf686924d13515795156a2e8893b3da88",
|
|
1262
1270
|
"src/docs-capability.ts": "bdeeb414649049b1cd4fa8008cada3a576318be51c43bec91bfa46a8e250c270",
|
|
1263
|
-
"src/enforce.ts": "
|
|
1264
|
-
"src/hooks.ts": "
|
|
1271
|
+
"src/enforce.ts": "c4811abe63efe4568f3cf26e21a152d1537e120cb3ce471daca32367cf6e2cda",
|
|
1272
|
+
"src/hooks.ts": "7e3dd5518701d2f3399bee919a68e801588822b173a648ed738c05c4a57231f1",
|
|
1265
1273
|
"src/index.ts": "4081f8b08d1d3ee9e15a9964143e53d9cfb94a5616ab3e58a180d24cc16dc381",
|
|
1266
1274
|
"src/integrity.ts": "f1ede7cb04924ae88e11917047277e264af6596b9759e381bd9c497cd34a797d",
|
|
1267
1275
|
"src/journey-docs.ts": "994d229376244c84212cff951032823068a76565dd2fd427b9d44e341bd14853",
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
schema_version: "1.0.0"
|
|
2
2
|
package: "@afokapu/atdd-bun"
|
|
3
3
|
node_corpus:
|
|
4
|
-
source: "
|
|
5
|
-
count:
|
|
4
|
+
source: "planner-nodes/nodes/"
|
|
5
|
+
count: 205
|
|
6
6
|
policy: >-
|
|
7
|
-
Every node is shipped as
|
|
7
|
+
Every node is shipped as Bun-owned planner reference material. A node is not
|
|
8
8
|
represented as enforced merely because it is present in this corpus.
|
|
9
9
|
|
|
10
10
|
# A provider implementation must name every canonical rule it realizes. `disposition` is
|
|
11
11
|
# this package's enforcement, always strict: atdd-bun fails on every finding, whatever the
|
|
12
|
-
# canonical node's own metadata says (the nodes are shipped
|
|
12
|
+
# canonical node's own metadata says (the nodes are authored and shipped by ATDD Bun). `coverage`
|
|
13
13
|
# describes the Bun predicate actually exercised, not an assertion that the entire
|
|
14
14
|
# prose convention has been ported.
|
|
15
15
|
canonical_bun_enforcement:
|
|
@@ -140,7 +140,7 @@ canonical_bun_enforcement:
|
|
|
140
140
|
|
|
141
141
|
reference_only:
|
|
142
142
|
selection: "every canonical planner node not named in canonical_bun_enforcement"
|
|
143
|
-
count:
|
|
143
|
+
count: 189
|
|
144
144
|
|
|
145
145
|
package_integrity_guard:
|
|
146
146
|
implementation_id: planner.plan-integrity.bun
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.execution-strategies
|
|
3
|
+
kind: family
|
|
4
|
+
status: active
|
|
5
|
+
name: Journey execution strategy catalog
|
|
6
|
+
statement: >-
|
|
7
|
+
Journey strategies are candidate ways to meet declared behavioral obligations. Choose for latency, throughput, cost, reliability, determinism, and complexity requirements; none is universally best. This convention does not authorize bypassing interlockings, trains, continuations, or acceptances.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: selection
|
|
10
|
+
text: >-
|
|
11
|
+
Begin with the reference strategy, then consider alternatives only when requirements or measured workloads justify complexity. Strategies are orthogonal and can combine.
|
|
12
|
+
- term_id: ownership
|
|
13
|
+
text: >-
|
|
14
|
+
Interlockings select guarded alternatives, journeys compose control flow, trains remain linear, and wagons can optimize their internals.
|
|
15
|
+
- term_id: governance
|
|
16
|
+
text: >-
|
|
17
|
+
Use only execution behavior actually supported by the plan and runtime. Missing fork/join, stream, or speculation capability requires separate implementation and accepted proof.
|
|
18
|
+
- term_id: evidence
|
|
19
|
+
text: >-
|
|
20
|
+
Preserve contracts, artifacts, prerequisites, side effects, error paths and terminal outcomes. Behavioral tests establish equivalence; reproducible benchmarks support performance claims. Observable behavior changes need their own accepted route.
|
|
21
|
+
notes: >-
|
|
22
|
+
Bun-owned planner guidance, not a new runtime mode or an independently enforced rule.
|
|
23
|
+
Existing journey, interlocking, and acceptance validators remain authoritative.
|
|
24
|
+
metadata:
|
|
25
|
+
severity: 3
|
|
26
|
+
disposition: advisory
|
|
27
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.adaptive
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Adaptive selection
|
|
6
|
+
statement: >-
|
|
7
|
+
Choose among already declared valid strategies using workload or resource signals while preserving accepted outputs and route obligations.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Consider only where measured workload variation justifies multiple strategies and switching overhead.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Use a deterministic inspectable selection policy and stable fallback; do not invent routes or suppress failure behavior when signals are absent.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test thresholds, missing metrics, fallback, oscillation and equivalence across workload classes; benchmark total cost.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Interlocking guards support deterministic alternatives; dynamic rescheduling needs new validated capabilities.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.batched
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Batched or fused work
|
|
6
|
+
statement: >-
|
|
7
|
+
Combine compatible calls or computations to amortize I/O, setup, serialization or scheduling overhead without changing accepted logical results.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Use for repeated homogeneous operations, database queries, vectorizable computation or repeated setup.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Preserve item identity, failure independence, transaction/authority boundaries, order and resource limits. Do not fuse across wagon ownership merely to reduce calls.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test mixed outcomes, batch boundaries, item-result mapping and equivalence; measure throughput and tail latency.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Normally an internal wagon implementation; no journey or interlocking schema change is needed.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.cached
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Cached or incremental results
|
|
6
|
+
statement: >-
|
|
7
|
+
Reuse valid results or recompute only affected portions when freshness and invalidation contracts make reuse safe.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Use for expensive repeatable reads and derivations with stable identities and tractable dependencies.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Define cache key, freshness, invalidation, authorization, tenant isolation and side effects. A hit cannot omit required permission or mutation.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test cold/warm paths, staleness, invalidation races, isolation and accepted-result equivalence; measure hit rate.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Cache work can be internal to a wagon; an explicit hit/miss route can use an existing interlocking.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.concurrent
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Concurrent branches
|
|
6
|
+
statement: >-
|
|
7
|
+
Run independent journey branches in parallel only when the topology explicitly specifies fan-out, dependency release, join, and failure semantics.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Use for independent expensive operations whose measured saving exceeds concurrency overhead.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Multiple incoming continuations are not a synchronization join. Current journeys allow one outgoing continuation or terminal per route and do not provide fork/join semantics.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Prove bounded concurrency, prerequisite satisfaction, joining, cancellation, failures and result equivalence; benchmark latency.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Cross-interlocking fan-out/fan-in is not yet supported. Within-wagon concurrency can honor existing contracts.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.conditional
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Guarded alternative
|
|
6
|
+
statement: >-
|
|
7
|
+
Use an interlocking's deterministic guards and priorities to select among declared linear train variants. A shortcut is a declared route, not an undeclared bypass.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Use for workload classes, cache hit/miss, fallbacks, recovery paths, or other mutually selected alternatives.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Every branch must have declared guard, train and accepted artifacts. Ambiguous matching and changed observable behavior are invalid without new acceptance.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test matching and nonmatching guards, ambiguity/priority resolution, errors and contract preservation.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Supported by current interlocking route resolution and journey continuations.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.pipelined
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Pipelined execution
|
|
6
|
+
statement: >-
|
|
7
|
+
Overlap producers and consumers through incremental artifact delivery only with an explicit streaming protocol.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Use for streaming/chunked workloads where first-result latency or memory dominates.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Preserve backpressure, ordering, partial failure, stream completion and resource bounds. A standard journey handoff does not define streaming.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test slow consumers, bounded buffers, chunk order, interruptions and equivalence; measure throughput and first-result latency.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Internal wagon streaming is possible; cross-interlocking streaming requires new declared runtime semantics.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.reference
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Reference execution
|
|
6
|
+
statement: >-
|
|
7
|
+
Follow declared interlocking routes and train continuations without additional scheduling or speculative transformations. Reference is the default, not a mandated slow path.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Choose when ordering matters, workload is small, behavior must be reproduced, or performance evidence does not justify an alternative.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Preserve guards, error/exception routes, artifacts, terminal outcomes, side effects, and ordering. A nominal path is not the full route space.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Use existing journey and acceptance tests to prove behavior; gather baseline measurements before claiming another strategy is faster.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
Supported by the current single-route continuation model.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
rule_id: planner.journey.strategy.speculative
|
|
3
|
+
kind: pattern
|
|
4
|
+
status: active
|
|
5
|
+
name: Speculative execution
|
|
6
|
+
statement: >-
|
|
7
|
+
Initiate reversible likely-needed work early only when discarded work and cancellation cannot change accepted behavior.
|
|
8
|
+
terms:
|
|
9
|
+
- term_id: applicability
|
|
10
|
+
text: >-
|
|
11
|
+
Consider when expensive future work is predictable and wasted work can be budgeted.
|
|
12
|
+
- term_id: constraints
|
|
13
|
+
text: >-
|
|
14
|
+
Never speculate authority commits, irreversible side effects, externally visible mutations or unauthorized data access. Define isolation, cancellation and resource budgets.
|
|
15
|
+
- term_id: evidence
|
|
16
|
+
text: >-
|
|
17
|
+
Test wrong predictions, cancellation races, duplicate attempts, isolation and total wasted work; measure net benefit.
|
|
18
|
+
- term_id: runtime_boundary
|
|
19
|
+
text: >-
|
|
20
|
+
No generic speculative journey scheduler exists; this convention cannot authorize undeclared execution.
|
|
21
|
+
notes: >-
|
|
22
|
+
Guidance for agents, not independent enforcement or a new runtime dispatch option.
|
|
23
|
+
Existing plan and source validators apply. Unimplemented orchestration behavior
|
|
24
|
+
cannot be inferred from a pattern.
|
|
25
|
+
metadata:
|
|
26
|
+
severity: 3
|
|
27
|
+
disposition: advisory
|
|
28
|
+
introduced_in: 0.1.0
|
package/relationships.yaml
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# are not imported; several do not relate two conventions at all.
|
|
8
8
|
schema_version: 1.0.0
|
|
9
9
|
graph_id: "@afokapu/atdd-bun"
|
|
10
|
-
nodes:
|
|
10
|
+
nodes:
|
|
11
11
|
- atdd-bun.planner.acceptance-identity
|
|
12
12
|
- atdd-bun.planner.identity-required
|
|
13
13
|
- atdd-bun.planner.identity-unique
|
|
@@ -213,7 +213,16 @@ nodes:
|
|
|
213
213
|
- planner.issue-body.graph-context-required
|
|
214
214
|
- planner.journey.continuation-closure
|
|
215
215
|
- planner.journey.definition
|
|
216
|
+
- planner.journey.execution-strategies
|
|
216
217
|
- planner.journey.interlocking-composed
|
|
218
|
+
- planner.journey.strategy.adaptive
|
|
219
|
+
- planner.journey.strategy.batched
|
|
220
|
+
- planner.journey.strategy.cached
|
|
221
|
+
- planner.journey.strategy.concurrent
|
|
222
|
+
- planner.journey.strategy.conditional
|
|
223
|
+
- planner.journey.strategy.pipelined
|
|
224
|
+
- planner.journey.strategy.reference
|
|
225
|
+
- planner.journey.strategy.speculative
|
|
217
226
|
- planner.plan.confirm-before-author
|
|
218
227
|
- planner.plan.confirm-binds-an-issue
|
|
219
228
|
- planner.plan.confirm-requires-interlocking-sanity
|
|
@@ -5279,3 +5288,93 @@ edges:
|
|
|
5279
5288
|
target_ref: coder.bun.phase-discipline
|
|
5280
5289
|
type: follows
|
|
5281
5290
|
origin: "@afokapu/atdd-bun"
|
|
5291
|
+
- confidence: 1
|
|
5292
|
+
constraint: mandatory
|
|
5293
|
+
control: internal
|
|
5294
|
+
foundation: finish_to_start
|
|
5295
|
+
reason: execution strategies inherit the existing journey ownership and continuation contract
|
|
5296
|
+
source_ref: planner.journey.execution-strategies
|
|
5297
|
+
strength: important
|
|
5298
|
+
target_ref: planner.journey.definition
|
|
5299
|
+
type: requires
|
|
5300
|
+
origin: "@afokapu/atdd-bun"
|
|
5301
|
+
- confidence: 1
|
|
5302
|
+
constraint: mandatory
|
|
5303
|
+
control: internal
|
|
5304
|
+
foundation: finish_to_start
|
|
5305
|
+
reason: the reference strategy requires the shared applicability and evidence principles
|
|
5306
|
+
source_ref: planner.journey.strategy.reference
|
|
5307
|
+
strength: important
|
|
5308
|
+
target_ref: planner.journey.execution-strategies
|
|
5309
|
+
type: requires
|
|
5310
|
+
origin: "@afokapu/atdd-bun"
|
|
5311
|
+
- confidence: 1
|
|
5312
|
+
constraint: mandatory
|
|
5313
|
+
control: internal
|
|
5314
|
+
foundation: finish_to_start
|
|
5315
|
+
reason: the conditional strategy requires the shared applicability and evidence principles
|
|
5316
|
+
source_ref: planner.journey.strategy.conditional
|
|
5317
|
+
strength: important
|
|
5318
|
+
target_ref: planner.journey.execution-strategies
|
|
5319
|
+
type: requires
|
|
5320
|
+
origin: "@afokapu/atdd-bun"
|
|
5321
|
+
- confidence: 1
|
|
5322
|
+
constraint: mandatory
|
|
5323
|
+
control: internal
|
|
5324
|
+
foundation: finish_to_start
|
|
5325
|
+
reason: the concurrent strategy requires the shared applicability and evidence principles
|
|
5326
|
+
source_ref: planner.journey.strategy.concurrent
|
|
5327
|
+
strength: important
|
|
5328
|
+
target_ref: planner.journey.execution-strategies
|
|
5329
|
+
type: requires
|
|
5330
|
+
origin: "@afokapu/atdd-bun"
|
|
5331
|
+
- confidence: 1
|
|
5332
|
+
constraint: mandatory
|
|
5333
|
+
control: internal
|
|
5334
|
+
foundation: finish_to_start
|
|
5335
|
+
reason: the pipelined strategy requires the shared applicability and evidence principles
|
|
5336
|
+
source_ref: planner.journey.strategy.pipelined
|
|
5337
|
+
strength: important
|
|
5338
|
+
target_ref: planner.journey.execution-strategies
|
|
5339
|
+
type: requires
|
|
5340
|
+
origin: "@afokapu/atdd-bun"
|
|
5341
|
+
- confidence: 1
|
|
5342
|
+
constraint: mandatory
|
|
5343
|
+
control: internal
|
|
5344
|
+
foundation: finish_to_start
|
|
5345
|
+
reason: the batched strategy requires the shared applicability and evidence principles
|
|
5346
|
+
source_ref: planner.journey.strategy.batched
|
|
5347
|
+
strength: important
|
|
5348
|
+
target_ref: planner.journey.execution-strategies
|
|
5349
|
+
type: requires
|
|
5350
|
+
origin: "@afokapu/atdd-bun"
|
|
5351
|
+
- confidence: 1
|
|
5352
|
+
constraint: mandatory
|
|
5353
|
+
control: internal
|
|
5354
|
+
foundation: finish_to_start
|
|
5355
|
+
reason: the cached strategy requires the shared applicability and evidence principles
|
|
5356
|
+
source_ref: planner.journey.strategy.cached
|
|
5357
|
+
strength: important
|
|
5358
|
+
target_ref: planner.journey.execution-strategies
|
|
5359
|
+
type: requires
|
|
5360
|
+
origin: "@afokapu/atdd-bun"
|
|
5361
|
+
- confidence: 1
|
|
5362
|
+
constraint: mandatory
|
|
5363
|
+
control: internal
|
|
5364
|
+
foundation: finish_to_start
|
|
5365
|
+
reason: the speculative strategy requires the shared applicability and evidence principles
|
|
5366
|
+
source_ref: planner.journey.strategy.speculative
|
|
5367
|
+
strength: important
|
|
5368
|
+
target_ref: planner.journey.execution-strategies
|
|
5369
|
+
type: requires
|
|
5370
|
+
origin: "@afokapu/atdd-bun"
|
|
5371
|
+
- confidence: 1
|
|
5372
|
+
constraint: mandatory
|
|
5373
|
+
control: internal
|
|
5374
|
+
foundation: finish_to_start
|
|
5375
|
+
reason: the adaptive strategy requires the shared applicability and evidence principles
|
|
5376
|
+
source_ref: planner.journey.strategy.adaptive
|
|
5377
|
+
strength: important
|
|
5378
|
+
target_ref: planner.journey.execution-strategies
|
|
5379
|
+
type: requires
|
|
5380
|
+
origin: "@afokapu/atdd-bun"
|
package/src/enforce.ts
CHANGED
|
@@ -44,7 +44,18 @@ export const profileImplementations: Record<ConcreteProfile, string[]> = {
|
|
|
44
44
|
|
|
45
45
|
/** Additional policy conventions a profile loads, whether local or contributed by an installed companion package. */
|
|
46
46
|
export const profileConventions: Record<ConcreteProfile, Array<{ rule_id: string; path: string }>> = {
|
|
47
|
-
traceability: [], topology: [], docs: [], planner: [
|
|
47
|
+
traceability: [], topology: [], docs: [], planner: [
|
|
48
|
+
{ rule_id: "planner.journey.definition", path: "planner-nodes/nodes/planner.journey.definition.convention.yaml" },
|
|
49
|
+
{ rule_id: "planner.journey.execution-strategies", path: "planner-nodes/nodes/planner.journey.execution-strategies.convention.yaml" },
|
|
50
|
+
{ rule_id: "planner.journey.strategy.adaptive", path: "planner-nodes/nodes/planner.journey.strategy.adaptive.convention.yaml" },
|
|
51
|
+
{ rule_id: "planner.journey.strategy.batched", path: "planner-nodes/nodes/planner.journey.strategy.batched.convention.yaml" },
|
|
52
|
+
{ rule_id: "planner.journey.strategy.cached", path: "planner-nodes/nodes/planner.journey.strategy.cached.convention.yaml" },
|
|
53
|
+
{ rule_id: "planner.journey.strategy.concurrent", path: "planner-nodes/nodes/planner.journey.strategy.concurrent.convention.yaml" },
|
|
54
|
+
{ rule_id: "planner.journey.strategy.conditional", path: "planner-nodes/nodes/planner.journey.strategy.conditional.convention.yaml" },
|
|
55
|
+
{ rule_id: "planner.journey.strategy.pipelined", path: "planner-nodes/nodes/planner.journey.strategy.pipelined.convention.yaml" },
|
|
56
|
+
{ rule_id: "planner.journey.strategy.reference", path: "planner-nodes/nodes/planner.journey.strategy.reference.convention.yaml" },
|
|
57
|
+
{ rule_id: "planner.journey.strategy.speculative", path: "planner-nodes/nodes/planner.journey.strategy.speculative.convention.yaml" },
|
|
58
|
+
], telemetry: [], coder: [{ rule_id: "coder.bun.phase-discipline", path: "conventions/coder.bun/coder.bun.phase-discipline.convention.yaml" }], tester: [], security: [],
|
|
48
59
|
architecture: [], metrics: [], runtime: [], interlocking: [], htmx: [], design: [],
|
|
49
60
|
flow: [
|
|
50
61
|
{ rule_id: "atdd-bun.review.behavioral-reconciliation", path: "conventions/atdd-bun.review/atdd-bun.review.behavioral-reconciliation.convention.yaml" },
|
package/src/hooks.ts
CHANGED
|
@@ -471,7 +471,7 @@ async function createWorkspace(state: Layout, target: { leaf: string; target: st
|
|
|
471
471
|
return bad(bookmark.err || bookmark.out || `bookmark ${branch} was not exported to the colocated Git repository`);
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
-
async function finishCandidate(state: Layout, cfg: HookPolicy): Promise<{ error: string } | { branch: string; tip: string
|
|
474
|
+
async function finishCandidate(state: Layout, cfg: HookPolicy): Promise<{ error: string } | { branch: string; tip: string }> {
|
|
475
475
|
if (state.current === state.primary || !inside(state.worktreeRoot, state.current)) return { error: `finish must run from a linked workspace beneath ${state.worktreeRoot}` };
|
|
476
476
|
const conflict = await noConflicts(state.current);
|
|
477
477
|
if (conflict.error !== undefined) return conflict;
|
|
@@ -489,23 +489,50 @@ async function finishCandidate(state: Layout, cfg: HookPolicy): Promise<{ error:
|
|
|
489
489
|
}
|
|
490
490
|
const tip = await branchCommit(state.primary, found.branch);
|
|
491
491
|
if (!tip || tip !== delivery) return { error: `bookmark ${found.branch} must point at the delivery revision before finish` };
|
|
492
|
-
|
|
493
|
-
return { branch: found.branch, tip
|
|
492
|
+
const undelivered = await deliveryError(state, found.branch, tip, cfg);
|
|
493
|
+
return undelivered ? { error: undelivered } : { branch: found.branch, tip };
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
async function jjRevision(root: string, commit: string): Promise<{ error: string } | { empty: boolean; conflict: boolean; parents: string[] }> {
|
|
497
|
+
const info = await jj(root, ["log", "-r", commit, "--no-graph", "-T", 'if(empty, "empty", "content") ++ " " ++ if(conflict, "conflict", "clean") ++ " " ++ parents.map(|p| p.commit_id()).join(" ")']);
|
|
498
|
+
if (info.code || !info.out) return { error: `could not inspect Jujutsu revision ${commit}: ${info.err || info.out}` };
|
|
499
|
+
const [emptiness, conflict, ...parents] = info.out.split(" ");
|
|
500
|
+
return { empty: emptiness === "empty", conflict: conflict === "conflict", parents };
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// A tip is delivered when it is an ancestor of the protected branch, or when it
|
|
504
|
+
// reaches such an ancestor only through empty single-parent changes (nothing to
|
|
505
|
+
// deliver). Content, conflicts, or merge shapes outside that chain fail closed.
|
|
506
|
+
async function deliveryError(state: Layout, branch: string, tip: string, cfg: HookPolicy): Promise<string | null> {
|
|
507
|
+
let commit = tip;
|
|
508
|
+
for (;;) {
|
|
509
|
+
const info = await jjRevision(state.primary, commit);
|
|
510
|
+
if ("error" in info) return info.error;
|
|
511
|
+
if (info.conflict) return `bookmark ${branch} has unresolved conflicts`;
|
|
512
|
+
if (!(await git(state.primary, ["merge-base", "--is-ancestor", commit, cfg.worktrees.primary_branch])).code) return null;
|
|
513
|
+
if (!info.empty || info.parents.length !== 1) return `branch ${branch} is not merged into ${cfg.worktrees.primary_branch} in the primary checkout`;
|
|
514
|
+
commit = info.parents[0]!;
|
|
515
|
+
}
|
|
494
516
|
}
|
|
495
517
|
|
|
496
|
-
// The
|
|
497
|
-
//
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
518
|
+
// The workspace name is never derived from the bookmark (bookmarks can be
|
|
519
|
+
// renamed). Resolve it from the JJ registry: exactly one registered workspace
|
|
520
|
+
// must resolve, by real path, to the current directory.
|
|
521
|
+
async function resolveWorkspace(state: Layout): Promise<{ error: string } | { name: string }> {
|
|
522
|
+
const listed = await jj(state.primary, ["workspace", "list", "-T", 'name ++ "\\n"']);
|
|
523
|
+
if (listed.code) return { error: `could not list Jujutsu workspaces: ${listed.err || listed.out}` };
|
|
524
|
+
const matches: string[] = [];
|
|
525
|
+
for (const name of listed.out.split("\n").filter(Boolean)) {
|
|
526
|
+
const recorded = await jj(state.primary, ["workspace", "root", "--name", name]);
|
|
527
|
+
if (!recorded.code && await realpath(recorded.out).catch(() => null) === state.current) matches.push(name);
|
|
528
|
+
}
|
|
529
|
+
return matches.length === 1 ? { name: matches[0]! } : { error: `${state.current} is not registered as exactly one Jujutsu workspace; found ${matches.length}` };
|
|
503
530
|
}
|
|
504
531
|
|
|
505
532
|
async function deleteBookmark(state: Layout, candidate: { branch: string; tip: string }, cfg: HookPolicy) {
|
|
506
533
|
const now = await branchCommit(state.primary, candidate.branch);
|
|
507
|
-
const merged = !(await
|
|
508
|
-
if (
|
|
534
|
+
const merged = now === candidate.tip && !(await deliveryError(state, candidate.branch, candidate.tip, cfg));
|
|
535
|
+
if (!merged) return `workspace removed, but bookmark ${candidate.branch} was not deleted: its tip changed or is no longer merged into ${cfg.worktrees.primary_branch}`;
|
|
509
536
|
const deleted = await jj(state.primary, ["bookmark", "delete", candidate.branch]);
|
|
510
537
|
return deleted.code ? `workspace removed, but bookmark deletion failed: ${deleted.err || deleted.out}` : null;
|
|
511
538
|
}
|
|
@@ -531,9 +558,9 @@ async function finishJjWorktree(root: string, deleteBranch: boolean, cfg: HookPo
|
|
|
531
558
|
if ("error" in state) return bad(state.error);
|
|
532
559
|
const candidate = await finishCandidate(state, cfg);
|
|
533
560
|
if ("error" in candidate) return bad(candidate.error);
|
|
534
|
-
const
|
|
535
|
-
if (
|
|
536
|
-
const removed = await jj(state.primary, ["workspace", "remove",
|
|
561
|
+
const workspace = await resolveWorkspace(state);
|
|
562
|
+
if ("error" in workspace) return bad(workspace.error);
|
|
563
|
+
const removed = await jj(state.primary, ["workspace", "remove", workspace.name]);
|
|
537
564
|
if (removed.code) return bad(removed.err || removed.out);
|
|
538
565
|
if (!deleteBranch) return { ok: true, message: `removed merged Jujutsu workspace ${state.current}` };
|
|
539
566
|
const deletionError = await deleteBookmark(state, candidate, cfg);
|
package/PLANNER_PORT.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# Planner port boundary
|
|
2
|
-
|
|
3
|
-
This package is Python-free for Bun enforcement. It deliberately does not claim
|
|
4
|
-
to port ATDD's full planner yet.
|
|
5
|
-
|
|
6
|
-
## Portable planner kernel
|
|
7
|
-
|
|
8
|
-
The package ships 196 canonical convention nodes in `planner-nodes/` and
|
|
9
|
-
21 schemas in `planner-schemas/`. It does not ship Python validator files:
|
|
10
|
-
they are executable Python/pytest code, not portable package assets. Port each
|
|
11
|
-
selected validator into Bun/TypeScript before enabling it in a `planner` profile.
|
|
12
|
-
|
|
13
|
-
1. Plan artifact schemas and canonical paths: wagon, feature, WMBT, acceptance,
|
|
14
|
-
train, contract, interlocking, and journey-topology documents.
|
|
15
|
-
2. URN and naming grammar, including wagon/feature/WMBT chains.
|
|
16
|
-
3. Plan graph references: wagon-to-feature, WMBT-to-acceptance, train registry
|
|
17
|
-
and participant/sequence references, contract registry references.
|
|
18
|
-
4. Static interlocking route declarations and their digest/registry invariants.
|
|
19
|
-
5. Journey topology closure across interlockings, bound through artifacts produced by the selected train.
|
|
20
|
-
|
|
21
|
-
## Port status
|
|
22
|
-
|
|
23
|
-
Enabled in the Bun `planner` profile (clean against ATDD's current plan and with a
|
|
24
|
-
dirty fixture per emitted rule):
|
|
25
|
-
|
|
26
|
-
- wagon identity and duplicate wagon slugs;
|
|
27
|
-
- wagon URN naming;
|
|
28
|
-
- duplicate produced artifact and feature declarations;
|
|
29
|
-
- produce/consume destination and source validity, including direct self-cycles;
|
|
30
|
-
- duplicate contract and telemetry ownership.
|
|
31
|
-
- train registry/document coherence in both directions.
|
|
32
|
-
- journey continuation closure across reachable interlocking routes.
|
|
33
|
-
|
|
34
|
-
The current source surface has 63 Python validator modules and 372 test cases.
|
|
35
|
-
The remaining modules are deliberately not represented as inert Python or as a
|
|
36
|
-
claim of parity. Each is admitted only after its applicability rules, clean real
|
|
37
|
-
plan baseline, and fault cases are reproduced under Bun.
|
|
38
|
-
|
|
39
|
-
These rules validate committed files and have no need for ATDD runtime state.
|
|
40
|
-
|
|
41
|
-
## Not a package concern
|
|
42
|
-
|
|
43
|
-
Do not port these into this package without a separate product decision:
|
|
44
|
-
|
|
45
|
-
- interactive `atdd plan` sessions, ratify/author state, and generated issue bodies;
|
|
46
|
-
- GitHub, local-store, coach, and runtime integrations;
|
|
47
|
-
- ATDD substrate admission, rule binding, dispositions, or suppressions.
|
|
48
|
-
|
|
49
|
-
They are orchestration capabilities, not Bun repository enforcement.
|
|
50
|
-
|
|
51
|
-
## Parity requirement
|
|
52
|
-
|
|
53
|
-
The current Python planner contains 197 convention nodes, 18 schemas, and 78 files
|
|
54
|
-
under its validators surface. A TypeScript port is accepted only when each selected
|
|
55
|
-
validator has a clean fixture, a fault fixture, and a Bun test proving both outcomes.
|