dsh-mnemon-strategy-default-three-tier 0.5.10 → 0.5.12
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/lib/index.js +27 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -69,6 +69,19 @@ the same role, the original ambiguity check applies rather than silently
|
|
|
69
69
|
choosing a Source. Projection limits are not token limits or delta injection;
|
|
70
70
|
capture guidance is not a background worker or a guarantee of model behavior.
|
|
71
71
|
|
|
72
|
+
## Sources with another role
|
|
73
|
+
|
|
74
|
+
An installed Source whose role is not `working-context`, `narrative` or
|
|
75
|
+
`durable-evidence` is not a failure and is not admitted either: the strategy
|
|
76
|
+
keeps composing the three tiers and returns one `unsupported-source-role`
|
|
77
|
+
entry per such Source in `ViewSpec.diagnostics`. The Host validates those
|
|
78
|
+
entries and merges them into `view.diagnostics`, so the turn's
|
|
79
|
+
`MNEMON VIEW AVAILABILITY` line and the View inspection name the Source and its
|
|
80
|
+
role. A diagnostic is an explanation, never authority: the Source still gets no
|
|
81
|
+
projection, Route or ActionOffer. Select the general Strategy to compose it;
|
|
82
|
+
an explicit `selection` still rejects unsupported roles. An unavailable Source keeps
|
|
83
|
+
the Host's own diagnostic instead.
|
|
84
|
+
|
|
72
85
|
Its own directory is a standalone project: install its declared dependencies,
|
|
73
86
|
then run `pnpm verify`. When developing against an unreleased Mnemon, install a
|
|
74
87
|
packed `dsh-mnemon` artifact as the peer instead of linking its source tree.
|
package/lib/index.js
CHANGED
|
@@ -510,11 +510,30 @@ const VIEW_ROLES = [
|
|
|
510
510
|
"narrative",
|
|
511
511
|
"durable-evidence"
|
|
512
512
|
];
|
|
513
|
+
/** The Host accepts at most 32 ViewSpec diagnostics; the summary keeps us inside it. */
|
|
514
|
+
const MAX_DIAGNOSTICS = 32;
|
|
513
515
|
function soleSource(sources, role) {
|
|
514
516
|
const matches = sources.filter((source) => source.role === role && source.availability !== "unavailable").sort((left, right) => left.sourceInstanceKey.localeCompare(right.sourceInstanceKey));
|
|
515
517
|
if (matches.length > 1) throw new Error(`default-three-tier View Strategy found ambiguous ${role} Sources; select an explicit Strategy`);
|
|
516
518
|
return matches[0];
|
|
517
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* Why an installed Source stays out of this View (#504). A custom role is not a
|
|
522
|
+
* failure, so it is explained instead of silently dropped; an unavailable Source
|
|
523
|
+
* already carries the Host's own diagnostic. Sorted by instance key so repeated
|
|
524
|
+
* composition stays deterministic.
|
|
525
|
+
*/
|
|
526
|
+
function unsupportedRoleDiagnostics(sources) {
|
|
527
|
+
const unsupported = sources.filter((source) => source.availability !== "unavailable" && !VIEW_ROLES.includes(source.role)).sort((left, right) => left.sourceInstanceKey.localeCompare(right.sourceInstanceKey));
|
|
528
|
+
const reported = unsupported.length <= MAX_DIAGNOSTICS ? unsupported : unsupported.slice(0, 31);
|
|
529
|
+
return [...reported.map((source) => ({
|
|
530
|
+
code: "unsupported-source-role",
|
|
531
|
+
message: `Installed Source ${source.sourceInstanceKey} declares the role "${source.role}", which the default-three-tier Strategy does not admit, so it contributes no projection, Routes or Actions to this View. Use the general Strategy to compose it.`
|
|
532
|
+
})), ...reported.length === unsupported.length ? [] : [{
|
|
533
|
+
code: "unsupported-source-role",
|
|
534
|
+
message: `${unsupported.length - reported.length} more installed Sources declare a role the default-three-tier Strategy does not admit.`
|
|
535
|
+
}]];
|
|
536
|
+
}
|
|
518
537
|
/** Pure View composition; no dependency on any Source implementation. */
|
|
519
538
|
const DEFAULT_THREE_TIER_VIEW_STRATEGY = defineMemoryStrategy({
|
|
520
539
|
createTurn: createThreeTierTurn,
|
|
@@ -536,7 +555,12 @@ const DEFAULT_THREE_TIER_VIEW_STRATEGY = defineMemoryStrategy({
|
|
|
536
555
|
workflows: ["idle-review", "runtime-capacity"]
|
|
537
556
|
},
|
|
538
557
|
compose(request, sources, contributions = []) {
|
|
539
|
-
|
|
558
|
+
const diagnostics = unsupportedRoleDiagnostics(sources);
|
|
559
|
+
const explained = (spec) => diagnostics.length === 0 ? spec : {
|
|
560
|
+
...spec,
|
|
561
|
+
diagnostics
|
|
562
|
+
};
|
|
563
|
+
if (contributions.length === 0) return explained(composeThreeTier(request, sources));
|
|
540
564
|
const policies = threeTierContributions(contributions);
|
|
541
565
|
const boundedRequest = policies.projection === void 0 ? request : {
|
|
542
566
|
...request,
|
|
@@ -545,7 +569,7 @@ const DEFAULT_THREE_TIER_VIEW_STRATEGY = defineMemoryStrategy({
|
|
|
545
569
|
maxProjectionCharacters: Math.min(request.budget.maxProjectionCharacters, policies.projection.maxProjectionCharacters)
|
|
546
570
|
}
|
|
547
571
|
};
|
|
548
|
-
const spec = policies.selection === void 0 ? composeThreeTier(boundedRequest, sources) : composeSelected(boundedRequest, sources, policies.selection);
|
|
572
|
+
const spec = explained(policies.selection === void 0 ? composeThreeTier(boundedRequest, sources) : composeSelected(boundedRequest, sources, policies.selection));
|
|
549
573
|
if (policies.capture !== void 0) {
|
|
550
574
|
const targets = spec.sources.filter((selected) => (policies.capture.sourceKeys === void 0 || policies.capture.sourceKeys.includes(selected.sourceInstanceKey)) && sources.some((source) => source.sourceInstanceKey === selected.sourceInstanceKey && source.actions.some((action) => selected.actionIds?.includes(action.id) && policies.capture.actionIds.includes(action.id) && action.authority === void 0 && ["write", "maintain"].includes(action.capability))));
|
|
551
575
|
if (targets.length > 0) {
|
|
@@ -627,7 +651,7 @@ function composeSelected(request, sources, selection) {
|
|
|
627
651
|
const selected = selection.sourceKeys.map((key) => {
|
|
628
652
|
const source = sources.find((source) => source.sourceInstanceKey === key);
|
|
629
653
|
if (source === void 0) throw new Error(`scoped three-tier Source is not installed: ${key}`);
|
|
630
|
-
if (!VIEW_ROLES.includes(source.role)) throw new Error(`unsupported scoped three-tier Source role: ${source.role}`);
|
|
654
|
+
if (!VIEW_ROLES.includes(source.role)) throw new Error(`unsupported scoped three-tier Source role: ${source.role} (${source.sourceInstanceKey}); default-three-tier admits ${VIEW_ROLES.join(", ")} only, so remove it from the selection or select the general Strategy`);
|
|
631
655
|
return source;
|
|
632
656
|
}).filter((source) => source.availability !== "unavailable");
|
|
633
657
|
const projected = selected.filter((source) => source.capabilities.includes("project"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mnemon-strategy-default-three-tier",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.12",
|
|
4
4
|
"description": "Explicit three-tier View Strategy for Composable View Memory.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^22.0.0",
|
|
39
|
-
"dsh-mnemon": "^0.5.
|
|
39
|
+
"dsh-mnemon": "^0.5.40",
|
|
40
40
|
"tsdown": "^0.22.0",
|
|
41
41
|
"typescript": "^5.9.0",
|
|
42
42
|
"vitest": "^3.2.0"
|