@haaaiawd/second-nature 0.2.9 → 0.2.13
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/index.js +102 -6
- package/openclaw.plugin.json +2 -5
- package/package.json +1 -1
- package/runtime/cli/commands/index.js +85 -11
- package/runtime/cli/host-capability/host-discovery-port.d.ts +85 -0
- package/runtime/cli/host-capability/host-discovery-port.js +137 -0
- package/runtime/cli/host-capability/probe-host-capability.js +1 -1
- package/runtime/cli/host-capability/types.d.ts +2 -7
- package/runtime/cli/host-capability/types.js +0 -5
- package/runtime/cli/ops/heartbeat-surface.d.ts +5 -3
- package/runtime/cli/ops/heartbeat-surface.js +38 -8
- package/runtime/cli/ops/ops-router.d.ts +6 -2
- package/runtime/cli/ops/ops-router.js +1275 -1147
- package/runtime/cli/ops/workspace-heartbeat-runner.js +2 -5
- package/runtime/connectors/base/normalized-evidence-content.d.ts +4 -0
- package/runtime/connectors/base/normalized-evidence-content.js +21 -2
- package/runtime/connectors/evidence-normalizer.js +32 -1
- package/runtime/connectors/manifest/manifest-schema.d.ts +2 -2
- package/runtime/connectors/registry/dynamic-connector-registry.js +16 -1
- package/runtime/connectors/services/connector-executor-adapter.js +54 -35
- package/runtime/core/second-nature/action/action-closure-recorder.d.ts +4 -0
- package/runtime/core/second-nature/action/action-closure-recorder.js +51 -38
- package/runtime/core/second-nature/action/action-proposal-builder.js +8 -34
- package/runtime/core/second-nature/action/policy-bound-dispatch.d.ts +2 -0
- package/runtime/core/second-nature/action/policy-bound-dispatch.js +10 -5
- package/runtime/core/second-nature/control-plane/accepted-projection-loader.js +1 -11
- package/runtime/core/second-nature/control-plane/cycle-finalizer.d.ts +82 -0
- package/runtime/core/second-nature/control-plane/cycle-finalizer.js +187 -0
- package/runtime/core/second-nature/control-plane/heartbeat-orchestrator.d.ts +1 -0
- package/runtime/core/second-nature/control-plane/heartbeat-orchestrator.js +23 -15
- package/runtime/core/second-nature/control-plane/real-runtime-spine.d.ts +2 -0
- package/runtime/core/second-nature/control-plane/real-runtime-spine.js +2 -1
- package/runtime/core/second-nature/guidance/guidance-proposal-consumer.d.ts +2 -1
- package/runtime/core/second-nature/guidance/guidance-proposal-consumer.js +4 -2
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +4 -3
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +3 -2
- package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +3 -2
- package/runtime/core/second-nature/orchestrator/intent-planner.js +4 -2
- package/runtime/core/second-nature/orchestrator/narrative-update.js +1 -2
- package/runtime/core/second-nature/orchestrator/platform-capability-router.d.ts +2 -2
- package/runtime/core/second-nature/orchestrator/platform-capability-router.js +1 -1
- package/runtime/core/second-nature/outreach/build-outreach-draft-request.js +2 -3
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.d.ts +2 -2
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.js +6 -1
- package/runtime/core/second-nature/outreach/judge-input-from-snapshot.js +3 -14
- package/runtime/core/second-nature/outreach/judge-outreach.d.ts +6 -5
- package/runtime/core/second-nature/perception/judgment-engine.js +10 -16
- package/runtime/core/second-nature/perception/perception-builder.js +15 -11
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +13 -15
- package/runtime/core/second-nature/quiet-dream/daily-rhythm-scheduler.js +40 -16
- package/runtime/core/second-nature/quiet-dream/dream-consolidation-runner.d.ts +5 -1
- package/runtime/core/second-nature/quiet-dream/dream-consolidation-runner.js +68 -29
- package/runtime/core/second-nature/quiet-dream/dream-scheduler.js +2 -3
- package/runtime/core/second-nature/quiet-dream/memory-projection-lifecycle.js +2 -13
- package/runtime/core/second-nature/quiet-dream/quiet-daily-review-builder.d.ts +1 -0
- package/runtime/core/second-nature/quiet-dream/quiet-daily-review-builder.js +34 -11
- package/runtime/core/second-nature/types.d.ts +2 -9
- package/runtime/dream/dream-engine.js +11 -4
- package/runtime/guidance/outreach-draft-schema.d.ts +12 -12
- package/runtime/guidance/persona-selection.js +5 -0
- package/runtime/guidance/template-registry.js +6 -1
- package/runtime/guidance/types.d.ts +2 -2
- package/runtime/observability/causal-loop-health.d.ts +2 -1
- package/runtime/observability/causal-loop-health.js +7 -0
- package/runtime/observability/living-loop-health-gate.js +2 -8
- package/runtime/observability/loop-stage-event-sink.js +6 -2
- package/runtime/observability/loop-status.d.ts +2 -0
- package/runtime/observability/loop-status.js +14 -1
- package/runtime/observability/services/heartbeat-digest-assembler.d.ts +3 -0
- package/runtime/observability/services/heartbeat-digest-assembler.js +9 -0
- package/runtime/observability/services/lived-experience-audit.d.ts +7 -7
- package/runtime/shared/degraded-status-classifier.d.ts +16 -0
- package/runtime/shared/degraded-status-classifier.js +68 -0
- package/runtime/shared/evidence-level-classifier.d.ts +61 -0
- package/runtime/shared/evidence-level-classifier.js +116 -0
- package/runtime/shared/provenance-tier.d.ts +37 -0
- package/runtime/shared/provenance-tier.js +97 -0
- package/runtime/shared/serialization.d.ts +17 -0
- package/runtime/shared/serialization.js +27 -0
- package/runtime/shared/setup-ack.d.ts +54 -0
- package/runtime/shared/setup-ack.js +108 -0
- package/runtime/shared/source-ref-compat.d.ts +26 -0
- package/runtime/shared/source-ref-compat.js +64 -0
- package/runtime/shared/types/goal.d.ts +4 -4
- package/runtime/shared/types/goal.js +1 -1
- package/runtime/shared/types/index.d.ts +1 -0
- package/runtime/shared/types/index.js +1 -3
- package/runtime/shared/types/source-ref.d.ts +2 -2
- package/runtime/shared/types/v7-entities.d.ts +5 -5
- package/runtime/shared/types/v7-entities.js +1 -1
- package/runtime/shared/types/v8-contracts.d.ts +13 -2
- package/runtime/storage/db/index.js +60 -12
- package/runtime/storage/db/migrations/index.js +4 -0
- package/runtime/storage/db/migrations/v8-004-schema-closure.d.ts +19 -0
- package/runtime/storage/db/migrations/v8-004-schema-closure.js +74 -0
- package/runtime/storage/db/migrations/v8-005-single-status-schema.d.ts +11 -0
- package/runtime/storage/db/migrations/v8-005-single-status-schema.js +16 -0
- package/runtime/storage/db/migrations/v8-006-loop-stage-event-proof-trace-columns.d.ts +9 -0
- package/runtime/storage/db/migrations/v8-006-loop-stage-event-proof-trace-columns.js +15 -0
- package/runtime/storage/db/schema/v8-entities.d.ts +65 -84
- package/runtime/storage/db/schema/v8-entities.js +8 -7
- package/runtime/storage/delivery/types.d.ts +2 -2
- package/runtime/storage/fallback/load-operator-fallback.d.ts +2 -2
- package/runtime/storage/fallback/operator-fallback-types.d.ts +2 -2
- package/runtime/storage/fallback/operator-fallback-view.d.ts +2 -2
- package/runtime/storage/index.d.ts +1 -1
- package/runtime/storage/life-evidence/types.d.ts +5 -5
- package/runtime/storage/quiet/quiet-artifact-types.d.ts +4 -4
- package/runtime/storage/quiet/quiet-artifact-writer.d.ts +2 -2
- package/runtime/storage/services/write-validation-gate.d.ts +1 -1
- package/runtime/storage/services/write-validation-gate.js +15 -3
- package/runtime/storage/snapshots/types.d.ts +8 -8
- package/runtime/storage/user-interest/types.d.ts +3 -3
- package/runtime/storage/v8-state-stores.d.ts +15 -3
- package/runtime/storage/v8-state-stores.js +60 -39
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppendOnlyAuditStore } from "../audit/append-only-audit-store.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { LifeEvidenceSourceRef } from "../../storage/life-evidence/types.js";
|
|
3
3
|
import type { DreamTrace } from "../../dream/types.js";
|
|
4
4
|
export type RuntimeScope = "rhythm" | "user_task" | "user_reply";
|
|
5
5
|
export type HeartbeatOutcome = "heartbeat_ok" | "intent_selected" | "denied" | "deferred" | "runtime_carrier_only" | "delivery_unavailable";
|
|
@@ -18,8 +18,8 @@ export interface DecisionTracePayload {
|
|
|
18
18
|
outreachVerdict?: "allow" | "deny" | "defer";
|
|
19
19
|
deliveryAuditId?: string;
|
|
20
20
|
reasonCodes: string[];
|
|
21
|
-
sourceRefs:
|
|
22
|
-
snapshotRef?:
|
|
21
|
+
sourceRefs: LifeEvidenceSourceRef[];
|
|
22
|
+
snapshotRef?: LifeEvidenceSourceRef;
|
|
23
23
|
createdAt: string;
|
|
24
24
|
}
|
|
25
25
|
export interface DeliveryAuditPayload {
|
|
@@ -31,7 +31,7 @@ export interface DeliveryAuditPayload {
|
|
|
31
31
|
recipientRef?: string;
|
|
32
32
|
status: DeliveryAuditStatus;
|
|
33
33
|
messageId?: string;
|
|
34
|
-
hostProofRef?:
|
|
34
|
+
hostProofRef?: LifeEvidenceSourceRef;
|
|
35
35
|
fallbackRef?: string;
|
|
36
36
|
ackDropMatched?: boolean;
|
|
37
37
|
hostVersion?: string;
|
|
@@ -45,8 +45,8 @@ export interface SourceCoverageAuditPayload {
|
|
|
45
45
|
decisionId?: string;
|
|
46
46
|
subjectType: "quiet_artifact" | "outreach_draft" | "guidance_payload" | "decision_trace" | "host_report";
|
|
47
47
|
subjectRef: string;
|
|
48
|
-
usedSourceRefs:
|
|
49
|
-
unresolvedRefs:
|
|
48
|
+
usedSourceRefs: LifeEvidenceSourceRef[];
|
|
49
|
+
unresolvedRefs: LifeEvidenceSourceRef[];
|
|
50
50
|
coverageRatio: number;
|
|
51
51
|
unsupportedClaims: string[];
|
|
52
52
|
status: GroundingStatus;
|
|
@@ -61,7 +61,7 @@ export interface GuidanceGroundingAuditPayload {
|
|
|
61
61
|
draftId?: string;
|
|
62
62
|
sceneType: "outreach" | "quiet_reflection" | "social" | "explain" | "user_reply_continuity" | "fallback_candidate";
|
|
63
63
|
groundingStatus: GroundingStatus;
|
|
64
|
-
usedSourceRefs:
|
|
64
|
+
usedSourceRefs: LifeEvidenceSourceRef[];
|
|
65
65
|
unsupportedClaims: string[];
|
|
66
66
|
guardViolations: string[];
|
|
67
67
|
deliveryWording?: "sendable" | "not_sent_fallback_candidate";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Degraded Status Classifier (T-OBS.R.8)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: map canonical V8ReasonCode values to precise operational states
|
|
5
|
+
* so that stage-level diagnostics never use the aggregate "degraded" string.
|
|
6
|
+
*
|
|
7
|
+
* Design authority:
|
|
8
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §4.1`
|
|
9
|
+
*
|
|
10
|
+
* Dependencies: `src/shared/types/v8-contracts.js`
|
|
11
|
+
* Boundary: pure function; no I/O.
|
|
12
|
+
* Test coverage: tests/unit/shared/degraded-status-classifier.test.ts
|
|
13
|
+
*/
|
|
14
|
+
import type { DegradedOperationResult, V8ReasonCode } from "./types/v8-contracts.js";
|
|
15
|
+
export type PreciseDegradedStatus = DegradedOperationResult["status"];
|
|
16
|
+
export declare function classifyDegradedStatus(reason: V8ReasonCode): PreciseDegradedStatus;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Degraded Status Classifier (T-OBS.R.8)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: map canonical V8ReasonCode values to precise operational states
|
|
5
|
+
* so that stage-level diagnostics never use the aggregate "degraded" string.
|
|
6
|
+
*
|
|
7
|
+
* Design authority:
|
|
8
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §4.1`
|
|
9
|
+
*
|
|
10
|
+
* Dependencies: `src/shared/types/v8-contracts.js`
|
|
11
|
+
* Boundary: pure function; no I/O.
|
|
12
|
+
* Test coverage: tests/unit/shared/degraded-status-classifier.test.ts
|
|
13
|
+
*/
|
|
14
|
+
const EMPTY_REASONS = new Set([
|
|
15
|
+
"evidence_batch_empty",
|
|
16
|
+
"evidence_content_missing",
|
|
17
|
+
"ingestion_empty",
|
|
18
|
+
"ingestion_no_data",
|
|
19
|
+
"quiet_empty_input",
|
|
20
|
+
]);
|
|
21
|
+
const BLOCKED_REASONS = new Set([
|
|
22
|
+
"source_refs_unresolved",
|
|
23
|
+
"proposal_missing_source_refs",
|
|
24
|
+
"judgment_missing_source_refs",
|
|
25
|
+
"quiet_redaction_blocked",
|
|
26
|
+
"dream_blocked_redaction",
|
|
27
|
+
"dream_blocked_no_content",
|
|
28
|
+
"dream_blocked_private_redacted",
|
|
29
|
+
"dream_blocked_credential",
|
|
30
|
+
"dream_blocked_validation_failed",
|
|
31
|
+
"dream_interval_active",
|
|
32
|
+
]);
|
|
33
|
+
const UNSAFE_REASONS = new Set([
|
|
34
|
+
"policy_denied_high_risk",
|
|
35
|
+
"policy_denied_breaker_open",
|
|
36
|
+
"closure_idempotency_conflict",
|
|
37
|
+
]);
|
|
38
|
+
const PARTIAL_REASONS = new Set([
|
|
39
|
+
"evidence_batch_truncated",
|
|
40
|
+
"perception_rules_only",
|
|
41
|
+
"dream_rules_only",
|
|
42
|
+
"dream_model_timeout",
|
|
43
|
+
"quiet_validation_failed",
|
|
44
|
+
"closure_downgraded_without_draft",
|
|
45
|
+
]);
|
|
46
|
+
const UNAVAILABLE_REASONS = new Set([
|
|
47
|
+
"state_unreadable",
|
|
48
|
+
"quiet_state_unreadable",
|
|
49
|
+
"ingestion_state_unreadable",
|
|
50
|
+
"stage_event_missing",
|
|
51
|
+
"execution_unavailable",
|
|
52
|
+
"guidance_unavailable",
|
|
53
|
+
"dream_scheduler_unavailable",
|
|
54
|
+
"policy_denied_missing_permission",
|
|
55
|
+
"closure_failed",
|
|
56
|
+
"closure_unavailable",
|
|
57
|
+
]);
|
|
58
|
+
export function classifyDegradedStatus(reason) {
|
|
59
|
+
if (EMPTY_REASONS.has(reason))
|
|
60
|
+
return "empty";
|
|
61
|
+
if (BLOCKED_REASONS.has(reason))
|
|
62
|
+
return "blocked";
|
|
63
|
+
if (UNSAFE_REASONS.has(reason))
|
|
64
|
+
return "unsafe";
|
|
65
|
+
if (PARTIAL_REASONS.has(reason))
|
|
66
|
+
return "partial";
|
|
67
|
+
return "unavailable";
|
|
68
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidenceLevelClassifier — Monotonic evidence-level taxonomy for operator-facing surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: classify how strongly a command/response is backed by runtime proof.
|
|
5
|
+
* Levels are ordered from weakest (carrier_ack) to strongest (durable_verified).
|
|
6
|
+
* A level may only stay the same or increase within one command; synthetic/carrier
|
|
7
|
+
* proofs can never be promoted to real_runtime or durable_verified.
|
|
8
|
+
*
|
|
9
|
+
* Design authority:
|
|
10
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §4.2, §4.3`
|
|
11
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/runtime-ops-system.md §2, §3.3`
|
|
12
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/observability-health-system.md §6.1`
|
|
13
|
+
*
|
|
14
|
+
* Dependencies: `src/shared/types/v8-contracts.js` (EvidenceLevel)
|
|
15
|
+
* Boundary: Pure classification functions; no storage or side effects.
|
|
16
|
+
* Test coverage: tests/unit/shared/evidence-level-classifier.test.ts
|
|
17
|
+
*/
|
|
18
|
+
import type { EvidenceLevel } from "./types/v8-contracts.js";
|
|
19
|
+
export type { EvidenceLevel };
|
|
20
|
+
export declare const EVIDENCE_LEVEL_ORDER: Record<EvidenceLevel, number>;
|
|
21
|
+
export interface EvidenceLevelProofInput {
|
|
22
|
+
/** Host/plugin/CLI produced an envelope but no Second Nature contract path ran. */
|
|
23
|
+
hasCarrierEnvelope?: boolean;
|
|
24
|
+
/** Static/fixture contract path ran without proving live state mutation. */
|
|
25
|
+
hasContractSmoke?: boolean;
|
|
26
|
+
/** Durable state was read or existing rows were observed. */
|
|
27
|
+
hasStatePresent?: boolean;
|
|
28
|
+
/** Current v8 living-loop command executed and produced stage + closure proof. */
|
|
29
|
+
hasCycleExecution?: boolean;
|
|
30
|
+
/** real_runtime proof was persisted and read back through normal read model. */
|
|
31
|
+
hasReadbackVerification?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Classify evidence level from observed proof flags.
|
|
35
|
+
* Returns the strongest level whose required proof is present.
|
|
36
|
+
*/
|
|
37
|
+
export declare function classifyEvidenceLevel(input: EvidenceLevelProofInput): EvidenceLevel;
|
|
38
|
+
/**
|
|
39
|
+
* Cap a candidate level by a maximum allowed level.
|
|
40
|
+
* Used to prevent carrier/smoke proofs from masquerading as real runtime health.
|
|
41
|
+
*/
|
|
42
|
+
export declare function capEvidenceLevel(candidate: EvidenceLevel, cap: EvidenceLevel): EvidenceLevel;
|
|
43
|
+
/**
|
|
44
|
+
* Promote a current level to a target level only if target is strictly stronger
|
|
45
|
+
* and promotion is supported by supplied proof.
|
|
46
|
+
*/
|
|
47
|
+
export declare function promoteEvidenceLevel(current: EvidenceLevel, target: EvidenceLevel, proof: EvidenceLevelProofInput): EvidenceLevel;
|
|
48
|
+
/**
|
|
49
|
+
* Aggregate multiple stage evidence levels into the minimum (weakest) level.
|
|
50
|
+
* A chain is only as strong as its weakest proven stage.
|
|
51
|
+
*/
|
|
52
|
+
export declare function minEvidenceLevel(levels: EvidenceLevel[]): EvidenceLevel;
|
|
53
|
+
/**
|
|
54
|
+
* Convenience: the strongest level achievable from the input proof set,
|
|
55
|
+
* but never exceeding a hard cap.
|
|
56
|
+
*/
|
|
57
|
+
export declare function classifyAndCapEvidenceLevel(input: EvidenceLevelProofInput, cap: EvidenceLevel): EvidenceLevel;
|
|
58
|
+
/**
|
|
59
|
+
* Map an evidence level to a human-readable operator note.
|
|
60
|
+
*/
|
|
61
|
+
export declare function evidenceLevelDescription(level: EvidenceLevel): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidenceLevelClassifier — Monotonic evidence-level taxonomy for operator-facing surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: classify how strongly a command/response is backed by runtime proof.
|
|
5
|
+
* Levels are ordered from weakest (carrier_ack) to strongest (durable_verified).
|
|
6
|
+
* A level may only stay the same or increase within one command; synthetic/carrier
|
|
7
|
+
* proofs can never be promoted to real_runtime or durable_verified.
|
|
8
|
+
*
|
|
9
|
+
* Design authority:
|
|
10
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §4.2, §4.3`
|
|
11
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/runtime-ops-system.md §2, §3.3`
|
|
12
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/observability-health-system.md §6.1`
|
|
13
|
+
*
|
|
14
|
+
* Dependencies: `src/shared/types/v8-contracts.js` (EvidenceLevel)
|
|
15
|
+
* Boundary: Pure classification functions; no storage or side effects.
|
|
16
|
+
* Test coverage: tests/unit/shared/evidence-level-classifier.test.ts
|
|
17
|
+
*/
|
|
18
|
+
export const EVIDENCE_LEVEL_ORDER = {
|
|
19
|
+
carrier_ack: 0,
|
|
20
|
+
contract_smoke: 1,
|
|
21
|
+
state_present: 2,
|
|
22
|
+
real_runtime: 3,
|
|
23
|
+
durable_verified: 4,
|
|
24
|
+
};
|
|
25
|
+
const LEVELS_BY_ORDER = [
|
|
26
|
+
"carrier_ack",
|
|
27
|
+
"contract_smoke",
|
|
28
|
+
"state_present",
|
|
29
|
+
"real_runtime",
|
|
30
|
+
"durable_verified",
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Classify evidence level from observed proof flags.
|
|
34
|
+
* Returns the strongest level whose required proof is present.
|
|
35
|
+
*/
|
|
36
|
+
export function classifyEvidenceLevel(input) {
|
|
37
|
+
if (input.hasReadbackVerification && input.hasCycleExecution) {
|
|
38
|
+
return "durable_verified";
|
|
39
|
+
}
|
|
40
|
+
if (input.hasCycleExecution) {
|
|
41
|
+
return "real_runtime";
|
|
42
|
+
}
|
|
43
|
+
if (input.hasStatePresent) {
|
|
44
|
+
return "state_present";
|
|
45
|
+
}
|
|
46
|
+
if (input.hasContractSmoke) {
|
|
47
|
+
return "contract_smoke";
|
|
48
|
+
}
|
|
49
|
+
if (input.hasCarrierEnvelope) {
|
|
50
|
+
return "carrier_ack";
|
|
51
|
+
}
|
|
52
|
+
// Default: carrier_ack when an envelope exists but no stronger proof was supplied.
|
|
53
|
+
return "carrier_ack";
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Cap a candidate level by a maximum allowed level.
|
|
57
|
+
* Used to prevent carrier/smoke proofs from masquerading as real runtime health.
|
|
58
|
+
*/
|
|
59
|
+
export function capEvidenceLevel(candidate, cap) {
|
|
60
|
+
if (EVIDENCE_LEVEL_ORDER[candidate] <= EVIDENCE_LEVEL_ORDER[cap]) {
|
|
61
|
+
return candidate;
|
|
62
|
+
}
|
|
63
|
+
return cap;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Promote a current level to a target level only if target is strictly stronger
|
|
67
|
+
* and promotion is supported by supplied proof.
|
|
68
|
+
*/
|
|
69
|
+
export function promoteEvidenceLevel(current, target, proof) {
|
|
70
|
+
const classified = classifyEvidenceLevel(proof);
|
|
71
|
+
if (EVIDENCE_LEVEL_ORDER[classified] >= EVIDENCE_LEVEL_ORDER[target]) {
|
|
72
|
+
return capEvidenceLevel(target, classified);
|
|
73
|
+
}
|
|
74
|
+
return current;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Aggregate multiple stage evidence levels into the minimum (weakest) level.
|
|
78
|
+
* A chain is only as strong as its weakest proven stage.
|
|
79
|
+
*/
|
|
80
|
+
export function minEvidenceLevel(levels) {
|
|
81
|
+
if (levels.length === 0)
|
|
82
|
+
return "carrier_ack";
|
|
83
|
+
let min = levels[0];
|
|
84
|
+
for (const level of levels) {
|
|
85
|
+
if (EVIDENCE_LEVEL_ORDER[level] < EVIDENCE_LEVEL_ORDER[min]) {
|
|
86
|
+
min = level;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return min;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Convenience: the strongest level achievable from the input proof set,
|
|
93
|
+
* but never exceeding a hard cap.
|
|
94
|
+
*/
|
|
95
|
+
export function classifyAndCapEvidenceLevel(input, cap) {
|
|
96
|
+
return capEvidenceLevel(classifyEvidenceLevel(input), cap);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Map an evidence level to a human-readable operator note.
|
|
100
|
+
*/
|
|
101
|
+
export function evidenceLevelDescription(level) {
|
|
102
|
+
switch (level) {
|
|
103
|
+
case "carrier_ack":
|
|
104
|
+
return "Host/plugin returned an envelope but no Second Nature contract path ran.";
|
|
105
|
+
case "contract_smoke":
|
|
106
|
+
return "Static or fixture contract path passed without live state mutation.";
|
|
107
|
+
case "state_present":
|
|
108
|
+
return "Durable state exists or was read, but no current cycle executed.";
|
|
109
|
+
case "real_runtime":
|
|
110
|
+
return "Current v8 living-loop command executed and produced stage/closure proof.";
|
|
111
|
+
case "durable_verified":
|
|
112
|
+
return "Real runtime proof persisted and read back through the normal read model.";
|
|
113
|
+
default:
|
|
114
|
+
return "Unknown evidence level.";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance Tier Validator (T-SH.R.6)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: enforce that real domain evidence lives in `sourceRefs`,
|
|
5
|
+
* runtime/policy/setup/host/packaging proofs live in `proofRefs`, and
|
|
6
|
+
* observability/audit/stage-event traces live in `traceRefs`.
|
|
7
|
+
*
|
|
8
|
+
* Design authority:
|
|
9
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §2.2`
|
|
10
|
+
*
|
|
11
|
+
* Dependencies: `src/shared/types/v8-contracts.js`
|
|
12
|
+
* Boundary: pure functions; no I/O.
|
|
13
|
+
* Test coverage: tests/unit/shared/provenance-tier.test.ts
|
|
14
|
+
*/
|
|
15
|
+
import type { SourceRef, ProvenanceBundle } from "./types/v8-contracts.js";
|
|
16
|
+
export interface ProvenanceValidationError {
|
|
17
|
+
ok: false;
|
|
18
|
+
field: "sourceRefs" | "proofRefs" | "traceRefs";
|
|
19
|
+
ref: SourceRef;
|
|
20
|
+
reason: string;
|
|
21
|
+
}
|
|
22
|
+
export type ProvenanceValidationResult = {
|
|
23
|
+
ok: true;
|
|
24
|
+
bundle: ProvenanceBundle;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
errors: ProvenanceValidationError[];
|
|
28
|
+
};
|
|
29
|
+
export declare function validateProvenanceTiers(bundle: ProvenanceBundle): ProvenanceValidationResult;
|
|
30
|
+
export declare function buildClosureProvenance(input: {
|
|
31
|
+
sourceRefs?: SourceRef[];
|
|
32
|
+
proofRefs?: SourceRef[];
|
|
33
|
+
traceRefs?: SourceRef[];
|
|
34
|
+
}): ProvenanceBundle;
|
|
35
|
+
export declare function cycleTraceRef(cycleId: string): SourceRef;
|
|
36
|
+
export declare function closureTraceRef(closureId: string): SourceRef;
|
|
37
|
+
export declare function decisionProofRef(decisionId: string): SourceRef;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance Tier Validator (T-SH.R.6)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: enforce that real domain evidence lives in `sourceRefs`,
|
|
5
|
+
* runtime/policy/setup/host/packaging proofs live in `proofRefs`, and
|
|
6
|
+
* observability/audit/stage-event traces live in `traceRefs`.
|
|
7
|
+
*
|
|
8
|
+
* Design authority:
|
|
9
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/shared-v8-contracts.md §2.2`
|
|
10
|
+
*
|
|
11
|
+
* Dependencies: `src/shared/types/v8-contracts.js`
|
|
12
|
+
* Boundary: pure functions; no I/O.
|
|
13
|
+
* Test coverage: tests/unit/shared/provenance-tier.test.ts
|
|
14
|
+
*/
|
|
15
|
+
const PROOF_FAMILIES = new Set([
|
|
16
|
+
"action_closure",
|
|
17
|
+
"audit",
|
|
18
|
+
"connector_result",
|
|
19
|
+
]);
|
|
20
|
+
const TRACE_FAMILIES = new Set([
|
|
21
|
+
"audit",
|
|
22
|
+
]);
|
|
23
|
+
function isSyntheticProof(ref) {
|
|
24
|
+
return (ref.uri.startsWith("sn://closure/") ||
|
|
25
|
+
ref.uri.startsWith("sn://decision/") ||
|
|
26
|
+
ref.uri.startsWith("sn://policy/") ||
|
|
27
|
+
ref.uri.startsWith("sn://execution/") ||
|
|
28
|
+
ref.uri.startsWith("sn://cycle/") ||
|
|
29
|
+
ref.uri.startsWith("sn://host/") ||
|
|
30
|
+
ref.uri.startsWith("sn://setup/") ||
|
|
31
|
+
PROOF_FAMILIES.has(ref.family));
|
|
32
|
+
}
|
|
33
|
+
function isTraceRef(ref) {
|
|
34
|
+
return (ref.uri.startsWith("sn://cycle/") ||
|
|
35
|
+
ref.uri.startsWith("sn://event/") ||
|
|
36
|
+
TRACE_FAMILIES.has(ref.family));
|
|
37
|
+
}
|
|
38
|
+
export function validateProvenanceTiers(bundle) {
|
|
39
|
+
const errors = [];
|
|
40
|
+
for (const ref of bundle.sourceRefs) {
|
|
41
|
+
if (isSyntheticProof(ref)) {
|
|
42
|
+
errors.push({
|
|
43
|
+
ok: false,
|
|
44
|
+
field: "sourceRefs",
|
|
45
|
+
ref,
|
|
46
|
+
reason: "Synthetic proof/trace ref must not live in sourceRefs",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const ref of bundle.proofRefs) {
|
|
51
|
+
if (isTraceRef(ref)) {
|
|
52
|
+
errors.push({
|
|
53
|
+
ok: false,
|
|
54
|
+
field: "proofRefs",
|
|
55
|
+
ref,
|
|
56
|
+
reason: "Trace ref must live in traceRefs, not proofRefs",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return errors.length === 0
|
|
61
|
+
? { ok: true, bundle }
|
|
62
|
+
: { ok: false, errors };
|
|
63
|
+
}
|
|
64
|
+
export function buildClosureProvenance(input) {
|
|
65
|
+
return {
|
|
66
|
+
sourceRefs: input.sourceRefs ?? [],
|
|
67
|
+
proofRefs: input.proofRefs ?? [],
|
|
68
|
+
traceRefs: input.traceRefs ?? [],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function cycleTraceRef(cycleId) {
|
|
72
|
+
return {
|
|
73
|
+
uri: `sn://cycle/${cycleId}`,
|
|
74
|
+
family: "audit",
|
|
75
|
+
id: cycleId,
|
|
76
|
+
redactionClass: "none",
|
|
77
|
+
resolveStatus: "resolvable",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function closureTraceRef(closureId) {
|
|
81
|
+
return {
|
|
82
|
+
uri: `sn://closure/${closureId}`,
|
|
83
|
+
family: "action_closure",
|
|
84
|
+
id: closureId,
|
|
85
|
+
redactionClass: "none",
|
|
86
|
+
resolveStatus: "resolvable",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function decisionProofRef(decisionId) {
|
|
90
|
+
return {
|
|
91
|
+
uri: `sn://decision/${decisionId}`,
|
|
92
|
+
family: "action_closure",
|
|
93
|
+
id: decisionId,
|
|
94
|
+
redactionClass: "none",
|
|
95
|
+
resolveStatus: "resolvable",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared serialization helpers for cross-system value types.
|
|
3
|
+
*
|
|
4
|
+
* Core logic:
|
|
5
|
+
* - `parseSourceRefs` / `serializeSourceRefs` provide the single round-trip
|
|
6
|
+
* implementation for `sourceRefsJson` / `source_refs_json` columns.
|
|
7
|
+
* - Failures are silent on read (return empty array) because malformed JSON
|
|
8
|
+
* in persisted state must not crash downstream consumers; callers that need
|
|
9
|
+
* to distinguish malformed rows should validate separately.
|
|
10
|
+
*
|
|
11
|
+
* Dependencies: `src/shared/types/v8-contracts.js` (SourceRef)
|
|
12
|
+
* Boundary: Pure functions; no storage or business logic.
|
|
13
|
+
* Test coverage: `tests/unit/shared/source-ref-serialization.test.ts`
|
|
14
|
+
*/
|
|
15
|
+
import type { SourceRef } from "./types/v8-contracts.js";
|
|
16
|
+
export declare function serializeSourceRefs(refs: SourceRef[]): string;
|
|
17
|
+
export declare function parseSourceRefs(json: string | null | undefined): SourceRef[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function serializeSourceRefs(refs) {
|
|
2
|
+
return JSON.stringify(refs);
|
|
3
|
+
}
|
|
4
|
+
function isSourceRef(value) {
|
|
5
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
6
|
+
return false;
|
|
7
|
+
const candidate = value;
|
|
8
|
+
return (typeof candidate.uri === "string" &&
|
|
9
|
+
typeof candidate.family === "string" &&
|
|
10
|
+
typeof candidate.id === "string" &&
|
|
11
|
+
typeof candidate.redactionClass === "string" &&
|
|
12
|
+
(candidate.sensitivityClass === undefined ||
|
|
13
|
+
typeof candidate.sensitivityClass === "string"));
|
|
14
|
+
}
|
|
15
|
+
export function parseSourceRefs(json) {
|
|
16
|
+
if (!json)
|
|
17
|
+
return [];
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(json);
|
|
20
|
+
if (Array.isArray(parsed) && parsed.every(isSourceRef))
|
|
21
|
+
return parsed;
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup Ack Truth Contract (T-ROS.R.8)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: define the canonical SetupAck schema and a validator that rejects
|
|
5
|
+
* `placedIn: "unspecified"`, missing fields, unknown writers, and hand-written
|
|
6
|
+
* files that do not satisfy the schema.
|
|
7
|
+
*
|
|
8
|
+
* Design authority:
|
|
9
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/runtime-ops-system.md §3.2`
|
|
10
|
+
*
|
|
11
|
+
* Dependencies: none (plain validation to keep plugin load lightweight)
|
|
12
|
+
* Boundary: Pure validation; no I/O.
|
|
13
|
+
* Test coverage: tests/unit/shared/setup-ack-validator.test.ts
|
|
14
|
+
*/
|
|
15
|
+
export declare const SETUP_ACK_SCHEMA_VERSION = 1;
|
|
16
|
+
export type SetupAckPlacement = "workspace_guide" | "host_skill_registry" | "agent_profile" | "manual_operator_instruction";
|
|
17
|
+
export type SetupAckWriter = "setup_ack_command" | "host_setup_bridge";
|
|
18
|
+
export interface SetupAck {
|
|
19
|
+
schemaVersion: typeof SETUP_ACK_SCHEMA_VERSION;
|
|
20
|
+
acknowledgedAt: string;
|
|
21
|
+
placedIn: SetupAckPlacement;
|
|
22
|
+
placementProofRef: string;
|
|
23
|
+
writer: SetupAckWriter;
|
|
24
|
+
hostName?: string;
|
|
25
|
+
hostVersion?: string;
|
|
26
|
+
acceptedBy?: string;
|
|
27
|
+
note?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SetupAckValidationResult {
|
|
30
|
+
ok: true;
|
|
31
|
+
ack: SetupAck;
|
|
32
|
+
}
|
|
33
|
+
export interface SetupAckValidationError {
|
|
34
|
+
ok: false;
|
|
35
|
+
field: string;
|
|
36
|
+
reason: string;
|
|
37
|
+
repairAction: string;
|
|
38
|
+
}
|
|
39
|
+
export type ValidateSetupAckResult = SetupAckValidationResult | {
|
|
40
|
+
ok: false;
|
|
41
|
+
errors: SetupAckValidationError[];
|
|
42
|
+
};
|
|
43
|
+
export declare function validateSetupAck(raw: Record<string, unknown>): ValidateSetupAckResult;
|
|
44
|
+
/**
|
|
45
|
+
* Check whether a raw marker object can be considered a complete ack.
|
|
46
|
+
* Hand-written files are treated as incomplete until verified.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isSetupAckComplete(raw: Record<string, unknown>): {
|
|
49
|
+
complete: true;
|
|
50
|
+
ack: SetupAck;
|
|
51
|
+
} | {
|
|
52
|
+
complete: false;
|
|
53
|
+
errors: SetupAckValidationError[];
|
|
54
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup Ack Truth Contract (T-ROS.R.8)
|
|
3
|
+
*
|
|
4
|
+
* Core logic: define the canonical SetupAck schema and a validator that rejects
|
|
5
|
+
* `placedIn: "unspecified"`, missing fields, unknown writers, and hand-written
|
|
6
|
+
* files that do not satisfy the schema.
|
|
7
|
+
*
|
|
8
|
+
* Design authority:
|
|
9
|
+
* - `.anws/v8/04_SYSTEM_DESIGN/runtime-ops-system.md §3.2`
|
|
10
|
+
*
|
|
11
|
+
* Dependencies: none (plain validation to keep plugin load lightweight)
|
|
12
|
+
* Boundary: Pure validation; no I/O.
|
|
13
|
+
* Test coverage: tests/unit/shared/setup-ack-validator.test.ts
|
|
14
|
+
*/
|
|
15
|
+
export const SETUP_ACK_SCHEMA_VERSION = 1;
|
|
16
|
+
const VALID_PLACEMENTS = new Set([
|
|
17
|
+
"workspace_guide",
|
|
18
|
+
"host_skill_registry",
|
|
19
|
+
"agent_profile",
|
|
20
|
+
"manual_operator_instruction",
|
|
21
|
+
]);
|
|
22
|
+
const VALID_WRITERS = new Set([
|
|
23
|
+
"setup_ack_command",
|
|
24
|
+
"host_setup_bridge",
|
|
25
|
+
]);
|
|
26
|
+
export function validateSetupAck(raw) {
|
|
27
|
+
const errors = [];
|
|
28
|
+
if (raw.schemaVersion !== SETUP_ACK_SCHEMA_VERSION) {
|
|
29
|
+
errors.push({
|
|
30
|
+
ok: false,
|
|
31
|
+
field: "schemaVersion",
|
|
32
|
+
reason: `schemaVersion must be ${SETUP_ACK_SCHEMA_VERSION}`,
|
|
33
|
+
repairAction: "Re-run setup_ack with a current client that writes schemaVersion=1.",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const placedIn = typeof raw.placedIn === "string" ? raw.placedIn : undefined;
|
|
37
|
+
if (!placedIn || placedIn === "unspecified") {
|
|
38
|
+
errors.push({
|
|
39
|
+
ok: false,
|
|
40
|
+
field: "placedIn",
|
|
41
|
+
reason: "placedIn is missing or 'unspecified'",
|
|
42
|
+
repairAction: "Provide a concrete placement target such as 'workspace_guide' or 'host_skill_registry'.",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else if (!VALID_PLACEMENTS.has(placedIn)) {
|
|
46
|
+
errors.push({
|
|
47
|
+
ok: false,
|
|
48
|
+
field: "placedIn",
|
|
49
|
+
reason: `placedIn '${placedIn}' is not a recognized placement target`,
|
|
50
|
+
repairAction: `Use one of: ${Array.from(VALID_PLACEMENTS).join(", ")}.`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const placementProofRef = typeof raw.placementProofRef === "string" ? raw.placementProofRef : undefined;
|
|
54
|
+
if (!placementProofRef || placementProofRef.trim().length === 0) {
|
|
55
|
+
errors.push({
|
|
56
|
+
ok: false,
|
|
57
|
+
field: "placementProofRef",
|
|
58
|
+
reason: "placementProofRef is missing or empty",
|
|
59
|
+
repairAction: "Provide a proof reference such as a host skill registry id, file path, or anchor URI.",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const writer = typeof raw.writer === "string" ? raw.writer : undefined;
|
|
63
|
+
if (!writer || !VALID_WRITERS.has(writer)) {
|
|
64
|
+
errors.push({
|
|
65
|
+
ok: false,
|
|
66
|
+
field: "writer",
|
|
67
|
+
reason: `writer '${writer ?? "missing"}' is not authorized`,
|
|
68
|
+
repairAction: `Writer must be one of: ${Array.from(VALID_WRITERS).join(", ")}.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const acknowledgedAt = typeof raw.acknowledgedAt === "string" ? raw.acknowledgedAt : undefined;
|
|
72
|
+
if (!acknowledgedAt || Number.isNaN(Date.parse(acknowledgedAt))) {
|
|
73
|
+
errors.push({
|
|
74
|
+
ok: false,
|
|
75
|
+
field: "acknowledgedAt",
|
|
76
|
+
reason: "acknowledgedAt is missing or not a valid ISO timestamp",
|
|
77
|
+
repairAction: "Re-run setup_ack so the client can write a fresh timestamp.",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (errors.length > 0) {
|
|
81
|
+
return { ok: false, errors };
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
ok: true,
|
|
85
|
+
ack: {
|
|
86
|
+
schemaVersion: SETUP_ACK_SCHEMA_VERSION,
|
|
87
|
+
acknowledgedAt: acknowledgedAt,
|
|
88
|
+
placedIn: placedIn,
|
|
89
|
+
placementProofRef: placementProofRef,
|
|
90
|
+
writer: writer,
|
|
91
|
+
hostName: typeof raw.hostName === "string" ? raw.hostName : undefined,
|
|
92
|
+
hostVersion: typeof raw.hostVersion === "string" ? raw.hostVersion : undefined,
|
|
93
|
+
acceptedBy: typeof raw.acceptedBy === "string" ? raw.acceptedBy : undefined,
|
|
94
|
+
note: typeof raw.note === "string" ? raw.note : undefined,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check whether a raw marker object can be considered a complete ack.
|
|
100
|
+
* Hand-written files are treated as incomplete until verified.
|
|
101
|
+
*/
|
|
102
|
+
export function isSetupAckComplete(raw) {
|
|
103
|
+
const result = validateSetupAck(raw);
|
|
104
|
+
if (result.ok) {
|
|
105
|
+
return { complete: true, ack: result.ack };
|
|
106
|
+
}
|
|
107
|
+
return { complete: false, errors: result.errors };
|
|
108
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SourceRef compatibility adapters.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: convert legacy v5/v7 source-ref shapes that used `kind` into
|
|
5
|
+
* the v8 canonical `SourceRef` shape (`family` + `redactionClass`).
|
|
6
|
+
* Dependencies: shared v8 contracts only.
|
|
7
|
+
* Boundary: compatibility at old/new system seams; canonical v8 modules should
|
|
8
|
+
* pass `SourceRef` directly without reintroducing local clones.
|
|
9
|
+
* Test coverage: Wave 113 typecheck and affected control-plane/host/life-evidence tests.
|
|
10
|
+
*/
|
|
11
|
+
import type { SourceRef, SourceRefFamily } from "./types/v8-contracts.js";
|
|
12
|
+
export type LegacySourceRefKind = "platform_item" | "workspace_artifact" | "decision_record" | "user_anchor" | "connector_result" | "host_report" | "fallback_artifact";
|
|
13
|
+
export interface LegacySourceRefLike {
|
|
14
|
+
id: string;
|
|
15
|
+
kind?: LegacySourceRefKind | string;
|
|
16
|
+
uri: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function sourceRefFamilyFromLegacyKind(kind: LegacySourceRefKind | string | undefined): SourceRefFamily;
|
|
19
|
+
export declare function legacyKindFromSourceRef(ref: SourceRef): LegacySourceRefKind;
|
|
20
|
+
export declare function toCanonicalSourceRef(ref: LegacySourceRefLike): SourceRef;
|
|
21
|
+
export declare function makeCanonicalSourceRef(input: {
|
|
22
|
+
id: string;
|
|
23
|
+
family: SourceRefFamily;
|
|
24
|
+
uri: string;
|
|
25
|
+
redactionClass?: SourceRef["redactionClass"];
|
|
26
|
+
}): SourceRef;
|