@mindexed/cfact 1.1.0 → 1.1.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/bin/claude-factory.js +56 -15
- package/package.json +6 -3
package/bin/claude-factory.js
CHANGED
|
@@ -648,7 +648,31 @@ function resolveSource(opts, pin) {
|
|
|
648
648
|
}
|
|
649
649
|
const base = channelBase(opts, pin);
|
|
650
650
|
if (base) {
|
|
651
|
-
|
|
651
|
+
// THIS CHANNEL NOW CARRIES A FALLBACK TOO, AND IT USED TO BE ARGUED IT DID
|
|
652
|
+
// NOT NEED ONE (FF-278, ADR-0203). ADR-0194 reasoned that the studio is
|
|
653
|
+
// "STRUCTURAL — version-keyed end to end", so both prefixes reach the same
|
|
654
|
+
// stored object and no fallback is warranted. That reasoning was correct
|
|
655
|
+
// about the STORE and wrong about the SERVING PATH: a filename validator sits
|
|
656
|
+
// in FRONT of the version-keyed lookup, and until it was widened and
|
|
657
|
+
// DEPLOYED it rejected `cfact-engine-*` outright. Measured on a real
|
|
658
|
+
// consumer: every version 400ed under the new name while the legacy name
|
|
659
|
+
// returned a valid tarball, so the DEFAULT channel was dead for every
|
|
660
|
+
// consumer on installer 1.1.0+ with no override.
|
|
661
|
+
//
|
|
662
|
+
// The general form is the part worth keeping: a structural claim about
|
|
663
|
+
// another repo must name WHICH CODE PATH it is about. "The store is keyed on
|
|
664
|
+
// version" and "the endpoint accepts this name" are different statements
|
|
665
|
+
// about different code, and nothing in this repo can check either one
|
|
666
|
+
// (rules/narrative-drift.md class 1). Where the claim is unverifiable from
|
|
667
|
+
// here, the addressed site owes a fallback — which costs one extra request
|
|
668
|
+
// ONLY on a failure that is already fatal, and nothing at all on success.
|
|
669
|
+
return {
|
|
670
|
+
kind: 'url',
|
|
671
|
+
via: 'studio',
|
|
672
|
+
ref: `${base.replace(/\/+$/, '')}/${asset}`,
|
|
673
|
+
fallbackRef: `${base.replace(/\/+$/, '')}/${LEGACY_ASSET(version)}`,
|
|
674
|
+
bearerEnv: ENGINE_TOKEN_NAMES,
|
|
675
|
+
};
|
|
652
676
|
}
|
|
653
677
|
|
|
654
678
|
// OPT-IN FALLBACK channel (ADR-0093, narrowed by ADR-0168): a GitHub Release
|
|
@@ -662,7 +686,8 @@ function resolveSource(opts, pin) {
|
|
|
662
686
|
// private repo, prefer the studio channel above, or --url with the exact asset.
|
|
663
687
|
const repo = opts.repo || pin.repo || DEFAULT_REPO;
|
|
664
688
|
const releaseBase = `https://github.com/${repo}/releases/download/engine-v${version}`;
|
|
665
|
-
// THIS CHANNEL NEEDS
|
|
689
|
+
// WHY THIS CHANNEL NEEDS ITS FALLBACK (ADR-0194; the studio has one too as of
|
|
690
|
+
// ADR-0203 — see below, and do NOT "restore the asymmetry"). The
|
|
666
691
|
// publisher attaches both asset names, but only to releases it publishes FROM
|
|
667
692
|
// NOW ON — and a published release is immutable (ADR-0128: an existing tag is
|
|
668
693
|
// an idempotent skip, never an asset re-upload). So on a NAME-keyed channel the
|
|
@@ -672,14 +697,19 @@ function resolveSource(opts, pin) {
|
|
|
672
697
|
//
|
|
673
698
|
// That is ADR-0192's read-vs-address proviso failing in the one direction the
|
|
674
699
|
// ADR did not take it. Its test asks whether something outside this repo keeps
|
|
675
|
-
// the old value resolving
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
// fallback for the other.
|
|
700
|
+
// the old value resolving, and here the answer is merely FORWARD-LOOKING: every
|
|
701
|
+
// already-published release carries the legacy asset alone. Where the proviso
|
|
702
|
+
// holds in only one direction, the addressed site owes a fallback for the other.
|
|
679
703
|
//
|
|
680
|
-
//
|
|
681
|
-
//
|
|
682
|
-
// problem it does not have.
|
|
704
|
+
// BOTH CHANNELS NOW CARRY ONE, and this comment used to say the opposite —
|
|
705
|
+
// "the studio needs no fallback, and giving it one would spend a wasted
|
|
706
|
+
// round-trip on the DEFAULT channel to paper over a problem it does not have."
|
|
707
|
+
// The studio DID have that problem (FF-278, ADR-0203): its serving-path
|
|
708
|
+
// validator rejected the new name for every version, and the round-trip is not
|
|
709
|
+
// wasted because a fallback costs a request only on a failure that is otherwise
|
|
710
|
+
// fatal. The two channels reach the same need by different routes — this one
|
|
711
|
+
// because published releases are immutable, the studio because a claim about
|
|
712
|
+
// another repo's code path could not be checked from here.
|
|
683
713
|
return {
|
|
684
714
|
kind: 'url',
|
|
685
715
|
via: 'github-releases',
|
|
@@ -996,12 +1026,23 @@ async function fetchToFile(source, destFile) {
|
|
|
996
1026
|
} catch (e) {
|
|
997
1027
|
die(`download failed — ${e.message}`);
|
|
998
1028
|
}
|
|
999
|
-
// A 404 with a fallback
|
|
1000
|
-
// asset name.
|
|
1001
|
-
//
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
1004
|
-
|
|
1029
|
+
// A 404 or a 400 with a fallback means THE NAME DID NOT RESOLVE: retry ONCE on
|
|
1030
|
+
// the legacy asset name. Still deliberately narrow — only when resolveSource
|
|
1031
|
+
// set a fallbackRef, and only once (two names exist, so a loop could only
|
|
1032
|
+
// re-request one of them).
|
|
1033
|
+
//
|
|
1034
|
+
// 400 joined 404 with ADR-0203. They are one condition stated by two servers:
|
|
1035
|
+
// a name-keyed store answers "no such asset" with 404, and a server that
|
|
1036
|
+
// VALIDATES the filename before looking anything up rejects it with 400 —
|
|
1037
|
+
// measured, verbatim `{"error":"Invalid engine tarball filename."}` from the
|
|
1038
|
+
// studio for every version under the new prefix. A 404-only trigger reads that
|
|
1039
|
+
// as fatal and never tries the name that works.
|
|
1040
|
+
//
|
|
1041
|
+
// 401 STAYS EXCLUDED, and that exclusion is the load-bearing half: a 401 means
|
|
1042
|
+
// the token, so retrying under a second name would burn a request and then
|
|
1043
|
+
// report the wrong cause — and the stripped-bearer diagnosis below exists
|
|
1044
|
+
// precisely because a 401 here is already hard to attribute.
|
|
1045
|
+
if ((res.status === 404 || res.status === 400) && source.fallbackRef) {
|
|
1005
1046
|
info(` not found under the current asset name; retrying ${source.fallbackRef}`);
|
|
1006
1047
|
try {
|
|
1007
1048
|
res = await fetch(source.fallbackRef, { headers, redirect: 'follow' });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindexed/cfact",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Clean Orthogonal Architecture Software Factory Framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claude-factory": "bin/claude-factory.js",
|
|
@@ -66,10 +66,13 @@
|
|
|
66
66
|
"publish:release": "node maintainer-hooks/publish-release.js",
|
|
67
67
|
"gate:consistency": "npm run gate:matrix-sync && npm run gate:compliance && npm run gate:doc-links && npm run gate:command-metadata && npm run gate:tracked-symlinks && npm run gate:agents-md-sync && npm run gate:ripple-coverage && npm run gate:profile-docs && npm run gate:registry && npm run gate:adr-template-edges && npm run gate:installer-publish-drift",
|
|
68
68
|
"gate:boundaries": "bash hooks/check-matrix.sh domain && bash hooks/check-matrix.sh components && bash hooks/check-matrix.sh controllers && bash hooks/check-matrix.sh secrets",
|
|
69
|
-
"ci": "npm run gate:consistency && npm run gate:boundaries && npm run gate:profile-coverage && npm run gate:changelog && npm run test:dc-generator && npm run test:substance-generator && npm run test:json-flush && npm run test:installer-exit && npm run test:installer-channel && npm run test:installer-wiring && npm run test:tar-invocation && npm run test:framework-agents-mcp && npm run test:controller-gates && npm run test:git-tree-sweep && npm run test:secrets-two-stage && npm run test:profile-paths && npm run test:registry-gate && npm run test:adr-template-edges && npm run test:adr-path-constants && npm run test:graph-strip && npm run test:graph-registry && npm run test:frontmatter-readers && npm run test:tarball-reproducible && npm run test:release-version && npm run test:consumer-checklist && npm run test:workflow-spine && npm run test:command-shape && npm run test:change-record && npm run test:installer-publish-drift && npm run test:grants-authored && npm run test:test-capability && npm run test:installer-lifecycle && npm run test:gate-three-state && npm run test:refresh-compliance && npm run test:gate-coverage && npm run test:installer-shadowing && npm run test:feature-record",
|
|
69
|
+
"ci": "npm run gate:consistency && npm run gate:boundaries && npm run gate:profile-coverage && npm run gate:changelog && npm run test:dc-generator && npm run test:substance-generator && npm run test:json-flush && npm run test:installer-exit && npm run test:installer-channel && npm run test:installer-wiring && npm run test:tar-invocation && npm run test:framework-agents-mcp && npm run test:controller-gates && npm run test:git-tree-sweep && npm run test:secrets-two-stage && npm run test:profile-paths && npm run test:registry-gate && npm run test:adr-template-edges && npm run test:adr-path-constants && npm run test:graph-strip && npm run test:graph-registry && npm run test:frontmatter-readers && npm run test:tarball-reproducible && npm run test:release-version && npm run test:consumer-checklist && npm run test:workflow-spine && npm run test:command-shape && npm run test:change-record && npm run test:installer-publish-drift && npm run test:grants-authored && npm run test:test-capability && npm run test:installer-lifecycle && npm run test:gate-three-state && npm run test:refresh-compliance && npm run test:gate-coverage && npm run test:installer-shadowing && npm run test:feature-record && npm run test:consumer-docs-migration && npm run test:npm-deprecation",
|
|
70
70
|
"test:gate-three-state": "node scripts/test-gate-three-state.js",
|
|
71
71
|
"test:refresh-compliance": "node scripts/test-refresh-compliance.js",
|
|
72
|
-
"test:gate-coverage": "node scripts/test-gate-coverage.js"
|
|
72
|
+
"test:gate-coverage": "node scripts/test-gate-coverage.js",
|
|
73
|
+
"test:consumer-docs-migration": "node scripts/test-consumer-docs-migration.js",
|
|
74
|
+
"test:sot-templates-pointer": "node scripts/test-sot-templates-pointer.js",
|
|
75
|
+
"test:npm-deprecation": "node scripts/test-npm-deprecation.js"
|
|
73
76
|
},
|
|
74
77
|
"keywords": [],
|
|
75
78
|
"author": "",
|