project-tiny-context-harness 0.7.2 → 0.7.4
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 +7 -5
- package/assets/README.md +49 -14
- package/assets/README.zh-CN.md +26 -13
- package/assets/agents/AGENTS_CORE.md +5 -5
- package/assets/context_templates/global.md +1 -0
- package/assets/skills/context_development_engineer/SKILL.md +4 -1
- package/assets/skills/context_uiux_design/SKILL.md +19 -6
- package/assets/skills/long-task-workflow/SKILL.md +10 -9
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +7 -5
- package/assets/skills/long-task-workflow/references/contract-authoring.md +24 -6
- package/assets/skills/long-task-workflow/references/evidence-design.md +14 -1
- package/assets/skills/source-plan-authoring/SKILL.md +2 -2
- package/dist/commands/long-task-authoring.js +25 -0
- package/dist/commands/long-task.js +3 -0
- package/dist/lib/design-md.d.ts +3 -0
- package/dist/lib/design-md.js +48 -55
- package/dist/lib/doctor.js +8 -0
- package/dist/lib/long-task-activation-validation.js +13 -2
- package/dist/lib/long-task-authoring-authority-preview.js +1 -0
- package/dist/lib/long-task-authority-material-diff.js +26 -0
- package/dist/lib/long-task-authority-materials.d.ts +2 -2
- package/dist/lib/long-task-authority-materials.js +6 -0
- package/dist/lib/long-task-authority-policy.d.ts +12 -0
- package/dist/lib/long-task-authority-policy.js +9 -0
- package/dist/lib/long-task-authority-revision-analysis.d.ts +33 -0
- package/dist/lib/long-task-authority-revision-analysis.js +91 -0
- package/dist/lib/long-task-authority-revision.js +93 -158
- package/dist/lib/long-task-authority-types.d.ts +7 -0
- package/dist/lib/long-task-authority.js +32 -3
- package/dist/lib/long-task-check-evidence-decoder.d.ts +2 -2
- package/dist/lib/long-task-check-evidence-decoder.js +11 -1
- package/dist/lib/long-task-check-execution-policy.d.ts +3 -0
- package/dist/lib/long-task-check-execution-policy.js +5 -0
- package/dist/lib/long-task-check-runner.js +2 -0
- package/dist/lib/long-task-check-shape.js +33 -3
- package/dist/lib/long-task-conformance-policy.d.ts +5 -0
- package/dist/lib/long-task-conformance-policy.js +35 -0
- package/dist/lib/long-task-contract-types.d.ts +14 -4
- package/dist/lib/long-task-delivery-compiler.js +1 -0
- package/dist/lib/long-task-delivery-parser.js +5 -2
- package/dist/lib/long-task-delivery-types.d.ts +2 -0
- package/dist/lib/long-task-delivery-types.js +2 -0
- package/dist/lib/long-task-delivery-validation.js +11 -0
- package/dist/lib/long-task-evidence-capability-codec.d.ts +2 -0
- package/dist/lib/long-task-evidence-capability-codec.js +231 -0
- package/dist/lib/long-task-evidence-capability-policy.d.ts +8 -0
- package/dist/lib/long-task-evidence-capability-policy.js +147 -0
- package/dist/lib/long-task-evidence-capability-runtime.d.ts +2 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +86 -0
- package/dist/lib/long-task-evidence-capability-types.d.ts +74 -0
- package/dist/lib/long-task-evidence-capability-types.js +1 -0
- package/dist/lib/long-task-evidence-findings.js +5 -1
- package/dist/lib/long-task-evidence-v2.js +38 -23
- package/dist/lib/long-task-final-v2.js +42 -1
- package/dist/lib/long-task-outcome-parser.js +14 -3
- package/dist/lib/long-task-playwright-evidence.d.ts +2 -1
- package/dist/lib/long-task-playwright-evidence.js +70 -2
- package/dist/lib/long-task-progress.js +4 -0
- package/dist/lib/long-task-root-shape.d.ts +1 -0
- package/dist/lib/long-task-root-shape.js +84 -3
- package/dist/lib/long-task-runner-environment.js +1 -1
- package/dist/lib/long-task-runner-freeze.d.ts +2 -2
- package/dist/lib/long-task-runner-freeze.js +3 -1
- package/dist/lib/long-task-runtime-types.d.ts +13 -0
- package/dist/lib/long-task-semantic-contract-types.d.ts +36 -0
- package/dist/lib/long-task-semantic-contract-types.js +1 -0
- package/dist/lib/long-task-semantic-drift-migration.d.ts +3 -0
- package/dist/lib/long-task-semantic-drift-migration.js +68 -0
- package/dist/lib/long-task-shape-primitives.d.ts +3 -0
- package/dist/lib/long-task-shape-primitives.js +25 -0
- package/dist/lib/long-task-stage-policy.d.ts +4 -0
- package/dist/lib/long-task-stage-policy.js +120 -0
- package/dist/lib/long-task-status-projection.d.ts +4 -1
- package/dist/lib/long-task-status-projection.js +63 -3
- package/dist/lib/long-task-status-v2.d.ts +11 -1
- package/dist/lib/long-task-status-v2.js +25 -3
- package/dist/lib/long-task-target-policy.d.ts +6 -0
- package/dist/lib/long-task-target-policy.js +127 -0
- package/dist/lib/migrations.js +29 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +61 -7
- package/migrations/README.md +7 -0
- package/package.json +2 -2
|
@@ -33,6 +33,7 @@ export function authoringRevisionPreview(contract, sourceHashes, sourceItems, co
|
|
|
33
33
|
schema_version: "long-task-delivery-v2",
|
|
34
34
|
task: active.authority_snapshot.task,
|
|
35
35
|
source_claims: active.authority_snapshot.source_claims,
|
|
36
|
+
stages: active.authority_snapshot.stages,
|
|
36
37
|
risk: active.authority_snapshot.risk,
|
|
37
38
|
global: active.authority_snapshot.global,
|
|
38
39
|
outcomes: active.authority_snapshot.outcomes,
|
|
@@ -89,13 +89,39 @@ function productClaimSemantics(contract) {
|
|
|
89
89
|
function flattenProductSemantics(projection) {
|
|
90
90
|
const fields = new Map([
|
|
91
91
|
["task.goal", projection.task_goal],
|
|
92
|
+
["task.target_profile.key", projection.target_profile.key],
|
|
93
|
+
["task.target_profile.description", projection.target_profile.description],
|
|
94
|
+
[
|
|
95
|
+
"task.target_profile.required_state",
|
|
96
|
+
projection.target_profile.required_state,
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
"task.target_profile.required_target_refs",
|
|
100
|
+
[...projection.target_profile.required_target_refs].sort(),
|
|
101
|
+
],
|
|
92
102
|
]);
|
|
103
|
+
for (const target of projection.execution_targets) {
|
|
104
|
+
const prefix = `task.execution_targets.${target.key}`;
|
|
105
|
+
fields.set(`${prefix}.description`, target.description);
|
|
106
|
+
fields.set(`${prefix}.role`, target.role);
|
|
107
|
+
fields.set(`${prefix}.runtime_family`, target.runtime_family);
|
|
108
|
+
fields.set(`${prefix}.root_entrypoint`, target.root_entrypoint);
|
|
109
|
+
}
|
|
110
|
+
for (const stage of projection.stages) {
|
|
111
|
+
const prefix = `stages.${stage.key}`;
|
|
112
|
+
fields.set(`${prefix}.title`, stage.title);
|
|
113
|
+
fields.set(`${prefix}.depends_on`, [...stage.depends_on].sort());
|
|
114
|
+
fields.set(`${prefix}.gate_outcome`, stage.gate_outcome);
|
|
115
|
+
}
|
|
93
116
|
for (const item of projection.global_non_goals)
|
|
94
117
|
fields.set(`global.product.non_goals.${item.key}`, item.statement);
|
|
95
118
|
for (const outcome of projection.outcomes) {
|
|
96
119
|
const prefix = `outcomes.${outcome.key}`;
|
|
97
120
|
fields.set(`${prefix}.title`, outcome.title);
|
|
121
|
+
fields.set(`${prefix}.stage`, outcome.stage);
|
|
98
122
|
fields.set(`${prefix}.observable_result`, outcome.observable_result);
|
|
123
|
+
fields.set(`${prefix}.success_path_required`, outcome.success_path_required);
|
|
124
|
+
fields.set(`${prefix}.degradation_path_required`, outcome.degradation_path_required);
|
|
99
125
|
fields.set(`${prefix}.owner.label`, outcome.owner.label);
|
|
100
126
|
fields.set(`${prefix}.owner.owner_surfaces`, outcome.owner.owner_surfaces);
|
|
101
127
|
for (const requirement of outcome.requirements) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AuthorityMaterialHashesV2, CompiledDeliveryContractV2, CompiledSourceItemV2, ContextAuthoritySnapshotV2, DeliveryContractV2, GlobalSemanticProjectionV2, NextAuthorityMaterialsV2, ProductSemanticProjectionV2 } from "./long-task-delivery-types.js";
|
|
2
|
-
export declare function computeAuthorityMaterials(contract: Pick<DeliveryContractV2, "task" | "global" | "outcomes">, sourceHashes: Record<string, string>, sourceItems: CompiledSourceItemV2[], contextSnapshot: ContextAuthoritySnapshotV2): NextAuthorityMaterialsV2;
|
|
2
|
+
export declare function computeAuthorityMaterials(contract: Pick<DeliveryContractV2, "task" | "global" | "outcomes" | "stages">, sourceHashes: Record<string, string>, sourceItems: CompiledSourceItemV2[], contextSnapshot: ContextAuthoritySnapshotV2): NextAuthorityMaterialsV2;
|
|
3
3
|
export declare function compiledAuthorityMaterials(compiled: CompiledDeliveryContractV2): NextAuthorityMaterialsV2;
|
|
4
4
|
export declare function authorityMaterialHashes(materials: NextAuthorityMaterialsV2): AuthorityMaterialHashesV2;
|
|
5
5
|
export declare function authorityMaterialsChanged(previous: NextAuthorityMaterialsV2, next: NextAuthorityMaterialsV2): boolean;
|
|
6
|
-
export declare function projectProductSemantics(contract: Pick<DeliveryContractV2, "task" | "global" | "outcomes">): ProductSemanticProjectionV2;
|
|
6
|
+
export declare function projectProductSemantics(contract: Pick<DeliveryContractV2, "task" | "global" | "outcomes" | "stages">): ProductSemanticProjectionV2;
|
|
7
7
|
export declare function projectGlobalSemantics(contract: Pick<DeliveryContractV2, "global">): GlobalSemanticProjectionV2;
|
|
@@ -28,11 +28,17 @@ export function authorityMaterialsChanged(previous, next) {
|
|
|
28
28
|
export function projectProductSemantics(contract) {
|
|
29
29
|
return {
|
|
30
30
|
task_goal: contract.task.goal,
|
|
31
|
+
target_profile: contract.task.target_profile,
|
|
32
|
+
execution_targets: [...contract.task.execution_targets].sort(keyOrder),
|
|
33
|
+
stages: [...contract.stages].sort(keyOrder),
|
|
31
34
|
global_non_goals: keyedStatements(contract.global.product.non_goals),
|
|
32
35
|
outcomes: [...contract.outcomes].sort(keyOrder).map((outcome) => ({
|
|
33
36
|
key: outcome.key,
|
|
34
37
|
title: outcome.title,
|
|
38
|
+
stage: outcome.stage,
|
|
35
39
|
observable_result: outcome.product.observable_result,
|
|
40
|
+
success_path_required: outcome.product.success_path_required,
|
|
41
|
+
degradation_path_required: outcome.product.degradation_path_required,
|
|
36
42
|
owner: {
|
|
37
43
|
label: outcome.product.owner.label,
|
|
38
44
|
owner_surfaces: [...outcome.product.owner_surfaces].sort(),
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export type AuthorityFieldPolicy = "identity" | "semantic_user_review" | "proof_additive" | "runner_authority" | "input_coverage" | "output_requirement" | "scope" | "readiness_only" | "descriptive_non_authoritative";
|
|
2
2
|
export declare const CHECK_AUTHORITY_POLICY: {
|
|
3
3
|
key: "identity";
|
|
4
|
+
journey_roles: "proof_additive";
|
|
5
|
+
execution_target: "semantic_user_review";
|
|
6
|
+
scenario: "proof_additive";
|
|
4
7
|
proof_surface: "semantic_user_review";
|
|
5
8
|
runner: "runner_authority";
|
|
6
9
|
verification_inputs: "proof_additive";
|
|
@@ -19,6 +22,8 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
|
|
|
19
22
|
source_paths: "scope";
|
|
20
23
|
context_refs: "scope";
|
|
21
24
|
context_snapshot_mode: "scope";
|
|
25
|
+
target_profile: "semantic_user_review";
|
|
26
|
+
execution_targets: "semantic_user_review";
|
|
22
27
|
};
|
|
23
28
|
readonly source_claim: {
|
|
24
29
|
key: "identity";
|
|
@@ -46,6 +51,7 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
|
|
|
46
51
|
readonly outcome: {
|
|
47
52
|
key: "identity";
|
|
48
53
|
title: "descriptive_non_authoritative";
|
|
54
|
+
stage: "semantic_user_review";
|
|
49
55
|
depends_on: "readiness_only";
|
|
50
56
|
product: "semantic_user_review";
|
|
51
57
|
technical: "semantic_user_review";
|
|
@@ -53,6 +59,8 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
|
|
|
53
59
|
};
|
|
54
60
|
readonly outcome_product: {
|
|
55
61
|
observable_result: "semantic_user_review";
|
|
62
|
+
success_path_required: "semantic_user_review";
|
|
63
|
+
degradation_path_required: "semantic_user_review";
|
|
56
64
|
owner: "semantic_user_review";
|
|
57
65
|
requirements: "semantic_user_review";
|
|
58
66
|
owner_surfaces: "semantic_user_review";
|
|
@@ -114,6 +122,9 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
|
|
|
114
122
|
};
|
|
115
123
|
readonly check: {
|
|
116
124
|
key: "identity";
|
|
125
|
+
journey_roles: "proof_additive";
|
|
126
|
+
execution_target: "semantic_user_review";
|
|
127
|
+
scenario: "proof_additive";
|
|
117
128
|
proof_surface: "semantic_user_review";
|
|
118
129
|
runner: "runner_authority";
|
|
119
130
|
verification_inputs: "proof_additive";
|
|
@@ -129,6 +140,7 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
|
|
|
129
140
|
criterion: "semantic_user_review";
|
|
130
141
|
claims: "proof_additive";
|
|
131
142
|
observation: "proof_additive";
|
|
143
|
+
evidence_capabilities: "proof_additive";
|
|
132
144
|
operator: "proof_additive";
|
|
133
145
|
expected: "proof_additive";
|
|
134
146
|
};
|
|
@@ -5,6 +5,8 @@ const TASK_AUTHORITY_POLICY = {
|
|
|
5
5
|
source_paths: "scope",
|
|
6
6
|
context_refs: "scope",
|
|
7
7
|
context_snapshot_mode: "scope",
|
|
8
|
+
target_profile: "semantic_user_review",
|
|
9
|
+
execution_targets: "semantic_user_review",
|
|
8
10
|
};
|
|
9
11
|
const SOURCE_CLAIM_AUTHORITY_POLICY = {
|
|
10
12
|
key: "identity",
|
|
@@ -32,6 +34,7 @@ const GLOBAL_ACCEPTANCE_AUTHORITY_POLICY = {
|
|
|
32
34
|
const OUTCOME_AUTHORITY_POLICY = {
|
|
33
35
|
key: "identity",
|
|
34
36
|
title: "descriptive_non_authoritative",
|
|
37
|
+
stage: "semantic_user_review",
|
|
35
38
|
depends_on: "readiness_only",
|
|
36
39
|
product: "semantic_user_review",
|
|
37
40
|
technical: "semantic_user_review",
|
|
@@ -39,6 +42,8 @@ const OUTCOME_AUTHORITY_POLICY = {
|
|
|
39
42
|
};
|
|
40
43
|
const OUTCOME_PRODUCT_AUTHORITY_POLICY = {
|
|
41
44
|
observable_result: "semantic_user_review",
|
|
45
|
+
success_path_required: "semantic_user_review",
|
|
46
|
+
degradation_path_required: "semantic_user_review",
|
|
42
47
|
owner: "semantic_user_review",
|
|
43
48
|
requirements: "semantic_user_review",
|
|
44
49
|
owner_surfaces: "semantic_user_review",
|
|
@@ -100,6 +105,9 @@ const OUTCOME_ACCEPTANCE_AUTHORITY_POLICY = {
|
|
|
100
105
|
};
|
|
101
106
|
export const CHECK_AUTHORITY_POLICY = {
|
|
102
107
|
key: "identity",
|
|
108
|
+
journey_roles: "proof_additive",
|
|
109
|
+
execution_target: "semantic_user_review",
|
|
110
|
+
scenario: "proof_additive",
|
|
103
111
|
proof_surface: "semantic_user_review",
|
|
104
112
|
runner: "runner_authority",
|
|
105
113
|
verification_inputs: "proof_additive",
|
|
@@ -115,6 +123,7 @@ const ASSERTION_AUTHORITY_POLICY = {
|
|
|
115
123
|
criterion: "semantic_user_review",
|
|
116
124
|
claims: "proof_additive",
|
|
117
125
|
observation: "proof_additive",
|
|
126
|
+
evidence_capabilities: "proof_additive",
|
|
118
127
|
operator: "proof_additive",
|
|
119
128
|
expected: "proof_additive",
|
|
120
129
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CompiledCheckV2, CompiledDeliveryContractV2, DeliveryContractV2 } from "./long-task-delivery-types.js";
|
|
2
|
+
export interface CheckRevisionAnalysis {
|
|
3
|
+
negative_assertions_removed: string[];
|
|
4
|
+
proof_surfaces_changed: string[];
|
|
5
|
+
runner_definitions_changed: string[];
|
|
6
|
+
verification_inputs_added: string[];
|
|
7
|
+
verification_inputs_removed_or_replaced: string[];
|
|
8
|
+
input_paths_added: string[];
|
|
9
|
+
input_paths_removed_or_narrowed: string[];
|
|
10
|
+
expected_output_paths_removed_or_weakened: string[];
|
|
11
|
+
artifacts_removed: string[];
|
|
12
|
+
environment_requirements_removed: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function analyzeCheckRevisions(beforeChecks: Map<string, CompiledCheckV2>, afterChecks: Map<string, CompiledCheckV2>): CheckRevisionAnalysis;
|
|
15
|
+
export interface OutcomeRevisionAnalysis {
|
|
16
|
+
owner_paths_expanded: string[];
|
|
17
|
+
owner_context_refs_removed: string[];
|
|
18
|
+
expected_change_paths_expanded: string[];
|
|
19
|
+
allowed_paths_expanded: string[];
|
|
20
|
+
forbidden_paths_removed: string[];
|
|
21
|
+
bindings_removed_or_expanded: string[];
|
|
22
|
+
obligations_removed_or_weakened: string[];
|
|
23
|
+
rollback_or_recovery_weakened: string[];
|
|
24
|
+
counterfactuals_removed: string[];
|
|
25
|
+
population_weakened: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function analyzeOutcomeRevisions(previous: CompiledDeliveryContractV2, next: DeliveryContractV2): OutcomeRevisionAnalysis;
|
|
28
|
+
export declare function keyedAuthorityChanges(before: Array<{
|
|
29
|
+
key: string;
|
|
30
|
+
}>, after: Array<{
|
|
31
|
+
key: string;
|
|
32
|
+
}>): string[];
|
|
33
|
+
export declare function selectedRevisionReasons(entries: Array<[reason: string, changed: boolean | unknown[]]>): string[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { addedInputPaths, addedVerificationInputs, bindingReductions, changedRunnerFields, counterfactualReductions, expandedPatterns, globalCounterfactualReductions, obligationReductions, removedExactValues, removedGlobalForbiddenPaths, removedOrNarrowedInputPaths, removedOrReplacedVerificationInputs, removedOrWeakenedExpectedOutputPaths, removedStructuredValues, rollbackReductions, same, } from "./long-task-authority-revision-details.js";
|
|
2
|
+
export function analyzeCheckRevisions(beforeChecks, afterChecks) {
|
|
3
|
+
const result = {
|
|
4
|
+
negative_assertions_removed: [],
|
|
5
|
+
proof_surfaces_changed: [],
|
|
6
|
+
runner_definitions_changed: [],
|
|
7
|
+
verification_inputs_added: [],
|
|
8
|
+
verification_inputs_removed_or_replaced: [],
|
|
9
|
+
input_paths_added: [],
|
|
10
|
+
input_paths_removed_or_narrowed: [],
|
|
11
|
+
expected_output_paths_removed_or_weakened: [],
|
|
12
|
+
artifacts_removed: [],
|
|
13
|
+
environment_requirements_removed: [],
|
|
14
|
+
};
|
|
15
|
+
for (const [identity, before] of beforeChecks) {
|
|
16
|
+
const after = afterChecks.get(identity);
|
|
17
|
+
if (!after)
|
|
18
|
+
continue;
|
|
19
|
+
for (const assertion of before.negative_assertions)
|
|
20
|
+
if (!after.negative_assertions.some((item) => same(item, assertion)))
|
|
21
|
+
result.negative_assertions_removed.push(`${identity}:${assertion.key}`);
|
|
22
|
+
if (before.proof_surface !== after.proof_surface)
|
|
23
|
+
result.proof_surfaces_changed.push(`${identity}:${before.proof_surface}->${after.proof_surface}`);
|
|
24
|
+
result.runner_definitions_changed.push(...changedRunnerFields(identity, before, after));
|
|
25
|
+
result.verification_inputs_added.push(...addedVerificationInputs(identity, before, after));
|
|
26
|
+
result.verification_inputs_removed_or_replaced.push(...removedOrReplacedVerificationInputs(identity, before, after));
|
|
27
|
+
result.input_paths_added.push(...addedInputPaths(identity, before, after));
|
|
28
|
+
result.input_paths_removed_or_narrowed.push(...removedOrNarrowedInputPaths(identity, before, after));
|
|
29
|
+
result.expected_output_paths_removed_or_weakened.push(...removedOrWeakenedExpectedOutputPaths(identity, before, after));
|
|
30
|
+
result.artifacts_removed.push(...removedExactValues(identity, before.artifact_globs, after.artifact_globs));
|
|
31
|
+
result.environment_requirements_removed.push(...removedStructuredValues(identity, before.environment_requirements, after.environment_requirements));
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
export function analyzeOutcomeRevisions(previous, next) {
|
|
36
|
+
const result = {
|
|
37
|
+
owner_paths_expanded: [],
|
|
38
|
+
owner_context_refs_removed: [],
|
|
39
|
+
expected_change_paths_expanded: [],
|
|
40
|
+
allowed_paths_expanded: [],
|
|
41
|
+
forbidden_paths_removed: removedGlobalForbiddenPaths(previous, next),
|
|
42
|
+
bindings_removed_or_expanded: [],
|
|
43
|
+
obligations_removed_or_weakened: [],
|
|
44
|
+
rollback_or_recovery_weakened: [],
|
|
45
|
+
counterfactuals_removed: globalCounterfactualReductions(previous, next),
|
|
46
|
+
population_weakened: [],
|
|
47
|
+
};
|
|
48
|
+
const previousOutcomes = new Map(previous.outcomes.map((outcome) => [outcome.key, outcome]));
|
|
49
|
+
for (const after of next.outcomes) {
|
|
50
|
+
const before = previousOutcomes.get(after.key);
|
|
51
|
+
if (!before)
|
|
52
|
+
continue;
|
|
53
|
+
result.owner_paths_expanded.push(...expandedPatterns(after.key, before.product.owner.path_globs, after.product.owner.path_globs));
|
|
54
|
+
result.owner_context_refs_removed.push(...removedExactValues(after.key, before.product.owner.context_refs, after.product.owner.context_refs));
|
|
55
|
+
result.expected_change_paths_expanded.push(...expandedPatterns(after.key, before.technical.expected_change_paths, after.technical.expected_change_paths));
|
|
56
|
+
result.allowed_paths_expanded.push(...expandedPatterns(after.key, before.technical.allowed_support_paths, after.technical.allowed_support_paths));
|
|
57
|
+
result.forbidden_paths_removed.push(...removedExactValues(after.key, before.technical.forbidden_paths, after.technical.forbidden_paths));
|
|
58
|
+
result.bindings_removed_or_expanded.push(...bindingReductions(before, after));
|
|
59
|
+
result.obligations_removed_or_weakened.push(...obligationReductions(before, after));
|
|
60
|
+
result.rollback_or_recovery_weakened.push(...rollbackReductions(before, after));
|
|
61
|
+
result.counterfactuals_removed.push(...counterfactualReductions(before, after));
|
|
62
|
+
if (before.acceptance.population &&
|
|
63
|
+
(!after.acceptance.population ||
|
|
64
|
+
!same(before.acceptance.population, after.acceptance.population)))
|
|
65
|
+
result.population_weakened.push(after.key);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
export function keyedAuthorityChanges(before, after) {
|
|
70
|
+
const beforeByKey = new Map(before.map((item) => [item.key, item]));
|
|
71
|
+
const afterByKey = new Map(after.map((item) => [item.key, item]));
|
|
72
|
+
return [
|
|
73
|
+
...before
|
|
74
|
+
.filter((item) => !afterByKey.has(item.key))
|
|
75
|
+
.map((item) => `${item.key}:removed`),
|
|
76
|
+
...after
|
|
77
|
+
.filter((item) => !beforeByKey.has(item.key))
|
|
78
|
+
.map((item) => `${item.key}:added`),
|
|
79
|
+
...before
|
|
80
|
+
.filter((item) => {
|
|
81
|
+
const candidate = afterByKey.get(item.key);
|
|
82
|
+
return candidate !== undefined && !same(item, candidate);
|
|
83
|
+
})
|
|
84
|
+
.map((item) => `${item.key}:changed`),
|
|
85
|
+
].sort();
|
|
86
|
+
}
|
|
87
|
+
export function selectedRevisionReasons(entries) {
|
|
88
|
+
return entries
|
|
89
|
+
.filter(([, changed]) => Array.isArray(changed) ? changed.length > 0 : changed)
|
|
90
|
+
.map(([reason]) => reason);
|
|
91
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { acceptanceSemanticsChanged, isMonotonicAcceptanceStrengthening, } from "./long-task-authority.js";
|
|
2
2
|
import { authorityMaterialRevisionDiff, changedProductClaimSemantics, sourceClaimAdditions, } from "./long-task-authority-material-diff.js";
|
|
3
|
+
import { analyzeCheckRevisions, analyzeOutcomeRevisions, keyedAuthorityChanges, selectedRevisionReasons, } from "./long-task-authority-revision-analysis.js";
|
|
4
|
+
import { addedValues, checkIndex, removedExactValues, removedValues, sourceClaimReductions, } from "./long-task-authority-revision-details.js";
|
|
3
5
|
import { compileProductClaimCoverage } from "./long-task-claims.js";
|
|
4
|
-
import { addedInputPaths, addedVerificationInputs, addedValues, bindingReductions, changedRunnerFields, checkIndex, counterfactualReductions, expandedPatterns, globalCounterfactualReductions, obligationReductions, removedExactValues, removedGlobalForbiddenPaths, removedOrNarrowedInputPaths, removedOrReplacedVerificationInputs, removedOrWeakenedExpectedOutputPaths, removedStructuredValues, removedValues, rollbackReductions, same, sourceClaimReductions, } from "./long-task-authority-revision-details.js";
|
|
5
6
|
import { verifierAuthorityDiff } from "./long-task-verifier-authority.js";
|
|
6
7
|
export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials, nextGlobalChecks, nextOutcomes, nextVerifier) {
|
|
7
8
|
const materialDiff = authorityMaterialRevisionDiff(previous, nextMaterials);
|
|
@@ -16,67 +17,12 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
16
17
|
const productClaimsAdded = addedValues(beforeClaimIds, afterClaimIds);
|
|
17
18
|
const productClaimsChanged = changedProductClaimSemantics(previous, next);
|
|
18
19
|
const checksRemoved = removedValues(new Set(beforeChecks.keys()), new Set(afterChecks.keys()));
|
|
19
|
-
const
|
|
20
|
-
const proofSurfacesChanged = [];
|
|
21
|
-
const runnerDefinitionsChanged = [];
|
|
22
|
-
const verificationInputsAdded = [];
|
|
23
|
-
const verificationInputsRemovedOrReplaced = [];
|
|
24
|
-
const inputPathsAdded = [];
|
|
25
|
-
const inputPathsRemovedOrNarrowed = [];
|
|
26
|
-
const expectedOutputPathsRemovedOrWeakened = [];
|
|
27
|
-
const artifactsRemoved = [];
|
|
28
|
-
const environmentRequirementsRemoved = [];
|
|
29
|
-
for (const [identity, before] of beforeChecks) {
|
|
30
|
-
const after = afterChecks.get(identity);
|
|
31
|
-
if (!after)
|
|
32
|
-
continue;
|
|
33
|
-
for (const assertion of before.negative_assertions)
|
|
34
|
-
if (!after.negative_assertions.some((item) => same(item, assertion)))
|
|
35
|
-
negativeAssertionsRemoved.push(`${identity}:${assertion.key}`);
|
|
36
|
-
if (before.proof_surface !== after.proof_surface)
|
|
37
|
-
proofSurfacesChanged.push(`${identity}:${before.proof_surface}->${after.proof_surface}`);
|
|
38
|
-
runnerDefinitionsChanged.push(...changedRunnerFields(identity, before, after));
|
|
39
|
-
verificationInputsAdded.push(...addedVerificationInputs(identity, before, after));
|
|
40
|
-
verificationInputsRemovedOrReplaced.push(...removedOrReplacedVerificationInputs(identity, before, after));
|
|
41
|
-
inputPathsAdded.push(...addedInputPaths(identity, before, after));
|
|
42
|
-
inputPathsRemovedOrNarrowed.push(...removedOrNarrowedInputPaths(identity, before, after));
|
|
43
|
-
expectedOutputPathsRemovedOrWeakened.push(...removedOrWeakenedExpectedOutputPaths(identity, before, after));
|
|
44
|
-
artifactsRemoved.push(...removedExactValues(identity, before.artifact_globs, after.artifact_globs));
|
|
45
|
-
environmentRequirementsRemoved.push(...removedStructuredValues(identity, before.environment_requirements, after.environment_requirements));
|
|
46
|
-
}
|
|
20
|
+
const checkChanges = analyzeCheckRevisions(beforeChecks, afterChecks);
|
|
47
21
|
const sourceClaimsRemovedOrChanged = sourceClaimReductions(previous.source_claims, next.source_claims);
|
|
48
22
|
const sourceClaimsAdded = sourceClaimAdditions(previous.source_claims, next.source_claims);
|
|
49
23
|
const sourcePathsRemovedOrReplaced = removedExactValues("task", previous.task.source_paths, next.task.source_paths);
|
|
50
|
-
const
|
|
51
|
-
const ownerContextRefsRemoved = [];
|
|
52
|
-
const expectedChangePathsExpanded = [];
|
|
53
|
-
const allowedPathsExpanded = [];
|
|
54
|
-
const forbiddenPathsRemoved = removedGlobalForbiddenPaths(previous, next);
|
|
55
|
-
const bindingsRemovedOrExpanded = [];
|
|
56
|
-
const obligationsRemovedOrWeakened = [];
|
|
57
|
-
const rollbackOrRecoveryWeakened = [];
|
|
58
|
-
const counterfactualsRemoved = globalCounterfactualReductions(previous, next);
|
|
59
|
-
const populationWeakened = [];
|
|
24
|
+
const outcomeChanges = analyzeOutcomeRevisions(previous, next);
|
|
60
25
|
const verifierDiff = verifierAuthorityDiff(previous.verifier_identity, nextVerifier);
|
|
61
|
-
const previousOutcomes = new Map(previous.outcomes.map((outcome) => [outcome.key, outcome]));
|
|
62
|
-
for (const after of next.outcomes) {
|
|
63
|
-
const before = previousOutcomes.get(after.key);
|
|
64
|
-
if (!before)
|
|
65
|
-
continue;
|
|
66
|
-
ownerPathsExpanded.push(...expandedPatterns(after.key, before.product.owner.path_globs, after.product.owner.path_globs));
|
|
67
|
-
ownerContextRefsRemoved.push(...removedExactValues(after.key, before.product.owner.context_refs, after.product.owner.context_refs));
|
|
68
|
-
expectedChangePathsExpanded.push(...expandedPatterns(after.key, before.technical.expected_change_paths, after.technical.expected_change_paths));
|
|
69
|
-
allowedPathsExpanded.push(...expandedPatterns(after.key, before.technical.allowed_support_paths, after.technical.allowed_support_paths));
|
|
70
|
-
forbiddenPathsRemoved.push(...removedExactValues(after.key, before.technical.forbidden_paths, after.technical.forbidden_paths));
|
|
71
|
-
bindingsRemovedOrExpanded.push(...bindingReductions(before, after));
|
|
72
|
-
obligationsRemovedOrWeakened.push(...obligationReductions(before, after));
|
|
73
|
-
rollbackOrRecoveryWeakened.push(...rollbackReductions(before, after));
|
|
74
|
-
counterfactualsRemoved.push(...counterfactualReductions(before, after));
|
|
75
|
-
if (before.acceptance.population &&
|
|
76
|
-
(!after.acceptance.population ||
|
|
77
|
-
!same(before.acceptance.population, after.acceptance.population)))
|
|
78
|
-
populationWeakened.push(after.key);
|
|
79
|
-
}
|
|
80
26
|
const riskChanged = previous.authority_hashes.risk_authority_hash !==
|
|
81
27
|
nextHashes.risk_authority_hash;
|
|
82
28
|
const acceptanceChanged = acceptanceSemanticsChanged(previous, next);
|
|
@@ -84,57 +30,64 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
84
30
|
const externalConfirmationsChanged = externalConfirmationChanges.length > 0;
|
|
85
31
|
const monotonic = isMonotonicAcceptanceStrengthening(previous, next);
|
|
86
32
|
const reductionReasons = [
|
|
87
|
-
...(
|
|
88
|
-
|
|
89
|
-
|
|
33
|
+
...selectedRevisionReasons([
|
|
34
|
+
["product_claim_added", productClaimsAdded],
|
|
35
|
+
["product_claim_removed", productClaimsRemoved],
|
|
36
|
+
["product_claim_changed", productClaimsChanged],
|
|
37
|
+
]),
|
|
90
38
|
...materialDiff.reduction_reasons,
|
|
91
|
-
...(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
39
|
+
...selectedRevisionReasons([
|
|
40
|
+
["check_removed", checksRemoved],
|
|
41
|
+
["negative_assertion_removed", checkChanges.negative_assertions_removed],
|
|
42
|
+
["proof_surface_changed", checkChanges.proof_surfaces_changed],
|
|
43
|
+
["source_claim_removed_or_changed", sourceClaimsRemovedOrChanged],
|
|
44
|
+
["source_claim_added", sourceClaimsAdded],
|
|
45
|
+
["source_path_removed_or_replaced", sourcePathsRemovedOrReplaced],
|
|
46
|
+
["owner_path_expanded", outcomeChanges.owner_paths_expanded],
|
|
47
|
+
["owner_context_ref_removed", outcomeChanges.owner_context_refs_removed],
|
|
48
|
+
[
|
|
49
|
+
"expected_change_path_expanded",
|
|
50
|
+
outcomeChanges.expected_change_paths_expanded,
|
|
51
|
+
],
|
|
52
|
+
["allowed_path_expanded", outcomeChanges.allowed_paths_expanded],
|
|
53
|
+
["forbidden_path_removed", outcomeChanges.forbidden_paths_removed],
|
|
54
|
+
["runner_definition_changed", checkChanges.runner_definitions_changed],
|
|
55
|
+
[
|
|
56
|
+
"verification_input_removed_or_replaced",
|
|
57
|
+
checkChanges.verification_inputs_removed_or_replaced,
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"input_path_coverage_reduced",
|
|
61
|
+
checkChanges.input_paths_removed_or_narrowed,
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
"expected_output_requirement_weakened",
|
|
65
|
+
checkChanges.expected_output_paths_removed_or_weakened,
|
|
66
|
+
],
|
|
67
|
+
["artifact_removed", checkChanges.artifacts_removed],
|
|
68
|
+
[
|
|
69
|
+
"environment_requirement_removed",
|
|
70
|
+
checkChanges.environment_requirements_removed,
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"binding_removed_or_expanded",
|
|
74
|
+
outcomeChanges.bindings_removed_or_expanded,
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
"obligation_removed_or_weakened",
|
|
78
|
+
outcomeChanges.obligations_removed_or_weakened,
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"rollback_or_recovery_weakened",
|
|
82
|
+
outcomeChanges.rollback_or_recovery_weakened,
|
|
83
|
+
],
|
|
84
|
+
["counterfactual_removed", outcomeChanges.counterfactuals_removed],
|
|
85
|
+
["population_weakened", outcomeChanges.population_weakened],
|
|
86
|
+
["verifier_content_changed", verifierDiff.verifier_content_changed],
|
|
87
|
+
["risk_changed_requires_review", riskChanged],
|
|
88
|
+
["external_confirmation_changed", externalConfirmationsChanged],
|
|
89
|
+
["acceptance_not_monotonic", acceptanceChanged && !monotonic],
|
|
90
|
+
]),
|
|
138
91
|
];
|
|
139
92
|
return {
|
|
140
93
|
product_claims_added: productClaimsAdded,
|
|
@@ -144,8 +97,8 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
144
97
|
global_semantics_changed: materialDiff.global_semantics_changed,
|
|
145
98
|
checks_added: addedValues(new Set(beforeChecks.keys()), new Set(afterChecks.keys())),
|
|
146
99
|
checks_removed: checksRemoved,
|
|
147
|
-
negative_assertions_removed:
|
|
148
|
-
proof_surfaces_changed:
|
|
100
|
+
negative_assertions_removed: checkChanges.negative_assertions_removed,
|
|
101
|
+
proof_surfaces_changed: checkChanges.proof_surfaces_changed,
|
|
149
102
|
source_claims_added: sourceClaimsAdded,
|
|
150
103
|
source_claims_removed_or_changed: sourceClaimsRemovedOrChanged,
|
|
151
104
|
source_paths_removed_or_replaced: sourcePathsRemovedOrReplaced,
|
|
@@ -157,60 +110,42 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
157
110
|
context_files_added: materialDiff.context_files_added,
|
|
158
111
|
context_files_removed: materialDiff.context_files_removed,
|
|
159
112
|
context_files_changed: materialDiff.context_files_changed,
|
|
160
|
-
owner_paths_expanded:
|
|
161
|
-
owner_context_refs_removed:
|
|
162
|
-
expected_change_paths_expanded:
|
|
163
|
-
allowed_paths_expanded:
|
|
164
|
-
forbidden_paths_removed:
|
|
165
|
-
runner_definitions_changed:
|
|
166
|
-
verification_inputs_added:
|
|
167
|
-
verification_inputs_removed_or_replaced:
|
|
168
|
-
input_paths_added:
|
|
169
|
-
input_paths_removed_or_narrowed:
|
|
170
|
-
expected_output_paths_removed_or_weakened:
|
|
171
|
-
artifacts_removed:
|
|
172
|
-
environment_requirements_removed:
|
|
173
|
-
bindings_removed_or_expanded:
|
|
174
|
-
obligations_removed_or_weakened:
|
|
175
|
-
rollback_or_recovery_weakened:
|
|
176
|
-
counterfactuals_removed:
|
|
177
|
-
population_weakened:
|
|
113
|
+
owner_paths_expanded: outcomeChanges.owner_paths_expanded,
|
|
114
|
+
owner_context_refs_removed: outcomeChanges.owner_context_refs_removed,
|
|
115
|
+
expected_change_paths_expanded: outcomeChanges.expected_change_paths_expanded,
|
|
116
|
+
allowed_paths_expanded: outcomeChanges.allowed_paths_expanded,
|
|
117
|
+
forbidden_paths_removed: outcomeChanges.forbidden_paths_removed,
|
|
118
|
+
runner_definitions_changed: checkChanges.runner_definitions_changed,
|
|
119
|
+
verification_inputs_added: checkChanges.verification_inputs_added,
|
|
120
|
+
verification_inputs_removed_or_replaced: checkChanges.verification_inputs_removed_or_replaced,
|
|
121
|
+
input_paths_added: checkChanges.input_paths_added,
|
|
122
|
+
input_paths_removed_or_narrowed: checkChanges.input_paths_removed_or_narrowed,
|
|
123
|
+
expected_output_paths_removed_or_weakened: checkChanges.expected_output_paths_removed_or_weakened,
|
|
124
|
+
artifacts_removed: checkChanges.artifacts_removed,
|
|
125
|
+
environment_requirements_removed: checkChanges.environment_requirements_removed,
|
|
126
|
+
bindings_removed_or_expanded: outcomeChanges.bindings_removed_or_expanded,
|
|
127
|
+
obligations_removed_or_weakened: outcomeChanges.obligations_removed_or_weakened,
|
|
128
|
+
rollback_or_recovery_weakened: outcomeChanges.rollback_or_recovery_weakened,
|
|
129
|
+
counterfactuals_removed: outcomeChanges.counterfactuals_removed,
|
|
130
|
+
population_weakened: outcomeChanges.population_weakened,
|
|
178
131
|
external_confirmations_changed: externalConfirmationsChanged,
|
|
179
132
|
external_confirmation_changes: externalConfirmationChanges,
|
|
180
133
|
...verifierDiff,
|
|
181
134
|
source_claims_changed: previous.authority_hashes.source_authority_hash !==
|
|
182
135
|
nextHashes.source_authority_hash,
|
|
183
136
|
risk_changed: riskChanged,
|
|
184
|
-
owner_or_path_boundary_changed:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
runner_or_verification_inputs_changed:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
technical_obligations_changed:
|
|
195
|
-
|
|
137
|
+
owner_or_path_boundary_changed: outcomeChanges.owner_paths_expanded.length > 0 ||
|
|
138
|
+
outcomeChanges.owner_context_refs_removed.length > 0 ||
|
|
139
|
+
outcomeChanges.expected_change_paths_expanded.length > 0 ||
|
|
140
|
+
outcomeChanges.allowed_paths_expanded.length > 0 ||
|
|
141
|
+
outcomeChanges.forbidden_paths_removed.length > 0 ||
|
|
142
|
+
outcomeChanges.bindings_removed_or_expanded.length > 0,
|
|
143
|
+
runner_or_verification_inputs_changed: checkChanges.runner_definitions_changed.length > 0 ||
|
|
144
|
+
checkChanges.verification_inputs_removed_or_replaced.length > 0 ||
|
|
145
|
+
checkChanges.input_paths_removed_or_narrowed.length > 0 ||
|
|
146
|
+
checkChanges.expected_output_paths_removed_or_weakened.length > 0,
|
|
147
|
+
technical_obligations_changed: outcomeChanges.obligations_removed_or_weakened.length > 0 ||
|
|
148
|
+
outcomeChanges.rollback_or_recovery_weakened.length > 0,
|
|
196
149
|
reduction_reasons: [...new Set(reductionReasons)],
|
|
197
150
|
};
|
|
198
151
|
}
|
|
199
|
-
function keyedAuthorityChanges(before, after) {
|
|
200
|
-
const beforeByKey = new Map(before.map((item) => [item.key, item]));
|
|
201
|
-
const afterByKey = new Map(after.map((item) => [item.key, item]));
|
|
202
|
-
return [
|
|
203
|
-
...before
|
|
204
|
-
.filter((item) => !afterByKey.has(item.key))
|
|
205
|
-
.map((item) => `${item.key}:removed`),
|
|
206
|
-
...after
|
|
207
|
-
.filter((item) => !beforeByKey.has(item.key))
|
|
208
|
-
.map((item) => `${item.key}:added`),
|
|
209
|
-
...before
|
|
210
|
-
.filter((item) => {
|
|
211
|
-
const candidate = afterByKey.get(item.key);
|
|
212
|
-
return candidate !== undefined && !same(item, candidate);
|
|
213
|
-
})
|
|
214
|
-
.map((item) => `${item.key}:changed`),
|
|
215
|
-
].sort();
|
|
216
|
-
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProofSurface } from "./long-task-contract-types.js";
|
|
2
|
+
import type { DeliveryStageV2, ExecutionTargetV2, TargetProfileV2 } from "./long-task-semantic-contract-types.js";
|
|
2
3
|
import type { CompiledSourceItemV2 } from "./long-task-source-authority-types.js";
|
|
3
4
|
import type { WorkspaceManifestV2 } from "./long-task-workspace-runtime-types.js";
|
|
4
5
|
export interface AuthorityHashesV2 {
|
|
@@ -10,6 +11,9 @@ export interface AuthorityHashesV2 {
|
|
|
10
11
|
}
|
|
11
12
|
export interface ProductSemanticProjectionV2 {
|
|
12
13
|
task_goal: string;
|
|
14
|
+
target_profile: TargetProfileV2;
|
|
15
|
+
execution_targets: ExecutionTargetV2[];
|
|
16
|
+
stages: DeliveryStageV2[];
|
|
13
17
|
global_non_goals: Array<{
|
|
14
18
|
key: string;
|
|
15
19
|
statement: string;
|
|
@@ -17,7 +21,10 @@ export interface ProductSemanticProjectionV2 {
|
|
|
17
21
|
outcomes: Array<{
|
|
18
22
|
key: string;
|
|
19
23
|
title: string;
|
|
24
|
+
stage: string;
|
|
20
25
|
observable_result: string;
|
|
26
|
+
success_path_required: boolean;
|
|
27
|
+
degradation_path_required: boolean;
|
|
21
28
|
owner: {
|
|
22
29
|
label: string;
|
|
23
30
|
owner_surfaces: string[];
|