project-tiny-context-harness 0.7.9 → 0.8.0
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/LICENSE +21 -21
- package/README.md +393 -380
- package/assets/README.md +567 -557
- package/assets/README.zh-CN.md +339 -326
- package/assets/agents/.gitkeep +1 -1
- package/assets/agents/AGENTS_CORE.md +66 -64
- package/assets/context_templates/architecture.md +33 -33
- package/assets/context_templates/area.md +39 -39
- package/assets/context_templates/context.toml +30 -30
- package/assets/context_templates/deployment.md +35 -35
- package/assets/context_templates/global.md +52 -51
- package/assets/context_templates/product-surface-contract.md +70 -70
- package/assets/context_templates/screen-contract.md +186 -177
- package/assets/context_templates/verification.md +32 -32
- package/assets/github/.gitkeep +1 -1
- package/assets/github/harness.yml +41 -41
- package/assets/make/.gitkeep +1 -1
- package/assets/make/ty-context.mk +48 -48
- package/assets/skills/context_development_engineer/SKILL.md +135 -131
- package/assets/skills/context_full_project_export/SKILL.md +70 -70
- package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
- package/assets/skills/context_product_plan/SKILL.md +88 -87
- package/assets/skills/context_surface_contract/SKILL.md +191 -191
- package/assets/skills/context_uiux_design/SKILL.md +158 -154
- package/assets/skills/design-resource-authoring/SKILL.md +84 -79
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +136 -108
- package/assets/skills/design-resource-authoring/references/open-design-provider.md +133 -127
- package/assets/skills/design-resource-authoring/references/resource-selection.md +173 -173
- package/assets/skills/design-system-authoring/SKILL.md +57 -57
- package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
- package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -47
- package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
- package/assets/skills/long-task-workflow/SKILL.md +100 -92
- package/assets/skills/long-task-workflow/agents/openai.yaml +4 -4
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +76 -59
- package/assets/skills/long-task-workflow/references/contract-authoring.md +116 -105
- package/assets/skills/long-task-workflow/references/evidence-design.md +78 -75
- package/assets/skills/long-task-workflow/references/source-authoring.md +101 -98
- package/assets/skills/normal-long-task/SKILL.md +12 -12
- package/assets/skills/source-plan-authoring/SKILL.md +14 -14
- package/assets/tools/validate_context.py +442 -442
- package/dist/commands/design-resource.d.ts +1 -0
- package/dist/commands/design-resource.js +32 -0
- package/dist/commands/index.js +4 -0
- package/dist/commands/long-task-command-args.d.ts +1 -0
- package/dist/commands/long-task-command-args.js +6 -0
- package/dist/commands/long-task-revision.js +16 -4
- package/dist/commands/long-task.js +12 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/design-md.js +3 -1
- package/dist/lib/design-resource-handoff-file-primitives.d.ts +4 -0
- package/dist/lib/design-resource-handoff-file-primitives.js +14 -0
- package/dist/lib/design-resource-handoff-file-validation.d.ts +2 -0
- package/dist/lib/design-resource-handoff-file-validation.js +142 -0
- package/dist/lib/design-resource-handoff-parser.d.ts +3 -0
- package/dist/lib/design-resource-handoff-parser.js +29 -0
- package/dist/lib/design-resource-handoff-policy.d.ts +3 -0
- package/dist/lib/design-resource-handoff-policy.js +36 -0
- package/dist/lib/design-resource-handoff-shape-evidence.d.ts +4 -0
- package/dist/lib/design-resource-handoff-shape-evidence.js +84 -0
- package/dist/lib/design-resource-handoff-shape-primitives.d.ts +9 -0
- package/dist/lib/design-resource-handoff-shape-primitives.js +44 -0
- package/dist/lib/design-resource-handoff-shape-structure.d.ts +5 -0
- package/dist/lib/design-resource-handoff-shape-structure.js +118 -0
- package/dist/lib/design-resource-handoff-shape.d.ts +2 -0
- package/dist/lib/design-resource-handoff-shape.js +75 -0
- package/dist/lib/design-resource-handoff-types.d.ts +139 -0
- package/dist/lib/design-resource-handoff-types.js +46 -0
- package/dist/lib/design-resource-handoff-validation-coverage.d.ts +4 -0
- package/dist/lib/design-resource-handoff-validation-coverage.js +168 -0
- package/dist/lib/design-resource-handoff-validation-primitives.d.ts +11 -0
- package/dist/lib/design-resource-handoff-validation-primitives.js +26 -0
- package/dist/lib/design-resource-handoff-validation-structure.d.ts +6 -0
- package/dist/lib/design-resource-handoff-validation-structure.js +93 -0
- package/dist/lib/design-resource-handoff-validation.d.ts +3 -0
- package/dist/lib/design-resource-handoff-validation.js +78 -0
- package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +3 -0
- package/dist/lib/design-resource-handoff-web-dependency-validation.js +70 -0
- package/dist/lib/long-task-activation-validation.js +14 -2
- package/dist/lib/long-task-authoring-preflight-diagnostics.js +7 -0
- package/dist/lib/long-task-authoring-preflight.js +39 -1
- package/dist/lib/long-task-authority-material-diff.js +14 -0
- package/dist/lib/long-task-authority-materials.js +21 -0
- package/dist/lib/long-task-authority-policy.d.ts +33 -0
- package/dist/lib/long-task-authority-policy.js +36 -0
- package/dist/lib/long-task-authority-revision-analysis.d.ts +1 -0
- package/dist/lib/long-task-authority-revision-analysis.js +30 -0
- package/dist/lib/long-task-authority-revision-brief.d.ts +3 -0
- package/dist/lib/long-task-authority-revision-brief.js +74 -0
- package/dist/lib/long-task-authority-revision-details.js +16 -16
- package/dist/lib/long-task-authority-revision-diagnosis.d.ts +1 -1
- package/dist/lib/long-task-authority-revision-diagnosis.js +8 -0
- package/dist/lib/long-task-authority-revision-enforcement.js +7 -3
- package/dist/lib/long-task-authority-revision-summary.d.ts +3 -0
- package/dist/lib/long-task-authority-revision-summary.js +133 -21
- package/dist/lib/long-task-authority-revision-types.d.ts +19 -1
- package/dist/lib/long-task-authority-revision.js +5 -0
- package/dist/lib/long-task-authority-types.d.ts +2 -0
- package/dist/lib/long-task-authority.js +10 -2
- package/dist/lib/long-task-check-execution-policy.js +2 -0
- package/dist/lib/long-task-claim-definitions.js +1 -5
- package/dist/lib/long-task-contract-types.d.ts +2 -0
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +7 -0
- package/dist/lib/long-task-counterfactual-sandbox.js +27 -1
- package/dist/lib/long-task-delivery-compiler.js +26 -8
- package/dist/lib/long-task-delivery-types.d.ts +1 -0
- package/dist/lib/long-task-delivery-types.js +1 -0
- package/dist/lib/long-task-delivery-validation.js +3 -0
- package/dist/lib/long-task-design-resource-handoff.d.ts +2 -0
- package/dist/lib/long-task-design-resource-handoff.js +177 -0
- package/dist/lib/long-task-evidence-capability-codec.js +19 -0
- package/dist/lib/long-task-evidence-capability-policy.js +4 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +25 -0
- package/dist/lib/long-task-evidence-capability-types.d.ts +9 -1
- package/dist/lib/long-task-outcome-parser.js +11 -1
- package/dist/lib/long-task-paths.d.ts +0 -1
- package/dist/lib/long-task-paths.js +0 -4
- package/dist/lib/long-task-playwright-case-evidence.d.ts +43 -0
- package/dist/lib/long-task-playwright-case-evidence.js +152 -0
- package/dist/lib/long-task-playwright-evidence.js +19 -152
- package/dist/lib/long-task-runner-freeze.d.ts +2 -2
- package/dist/lib/long-task-runner-freeze.js +2 -1
- package/dist/lib/long-task-runtime-types.d.ts +2 -0
- package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
- package/dist/lib/long-task-semantic-drift-migration.js +6 -1
- package/dist/lib/long-task-shape-primitives.d.ts +1 -1
- package/dist/lib/long-task-shape-primitives.js +1 -0
- package/dist/lib/long-task-status-v2.js +12 -7
- package/dist/lib/long-task-ui-design-policy.d.ts +17 -0
- package/dist/lib/long-task-ui-design-policy.js +128 -0
- package/dist/lib/long-task-ui-surface-policy.d.ts +4 -0
- package/dist/lib/long-task-ui-surface-policy.js +109 -0
- package/dist/lib/long-task-ui-surface-shape.d.ts +2 -0
- package/dist/lib/long-task-ui-surface-shape.js +94 -0
- package/dist/lib/long-task-ui-surface-types.d.ts +44 -0
- package/dist/lib/long-task-ui-surface-types.js +1 -0
- package/dist/lib/long-task-ui-surface-validation.d.ts +11 -0
- package/dist/lib/long-task-ui-surface-validation.js +62 -0
- package/dist/lib/long-task-verification-preview.d.ts +55 -0
- package/dist/lib/long-task-verification-preview.js +120 -0
- package/dist/lib/long-task-verifier-v2.js +11 -18
- package/dist/lib/long-task-workspace-scope.d.ts +38 -0
- package/dist/lib/long-task-workspace-scope.js +121 -0
- package/dist/lib/long-task-workspace.d.ts +1 -0
- package/dist/lib/long-task-workspace.js +73 -9
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +84 -2
- package/migrations/README.md +7 -7
- package/package.json +3 -3
- package/source-mappings.yaml +25 -25
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { DESIGN_RESOURCE_VERIFICATION_METHODS } from "./design-resource-handoff-types.js";
|
|
2
|
+
import { array, key, literal, object, repositoryFile, repositoryFiles, string, strings, } from "./long-task-shape-primitives.js";
|
|
3
|
+
export function parseSurfaceBindings(value, label) {
|
|
4
|
+
return array(value, label).map((item, index) => {
|
|
5
|
+
const itemLabel = `${label}[${index}]`;
|
|
6
|
+
const row = object(item, itemLabel, [
|
|
7
|
+
"key",
|
|
8
|
+
"surface_ref",
|
|
9
|
+
"target_ref",
|
|
10
|
+
"control_refs",
|
|
11
|
+
"route_binding_ref",
|
|
12
|
+
"component_binding_refs",
|
|
13
|
+
"root_journey_check_ref",
|
|
14
|
+
"entry_action_ref",
|
|
15
|
+
"design_targets",
|
|
16
|
+
"acceptance_blockers",
|
|
17
|
+
]);
|
|
18
|
+
return {
|
|
19
|
+
key: key(row.key, `${itemLabel}.key`),
|
|
20
|
+
surface_ref: string(row.surface_ref, `${itemLabel}.surface_ref`),
|
|
21
|
+
target_ref: key(row.target_ref, `${itemLabel}.target_ref`),
|
|
22
|
+
control_refs: keys(row.control_refs, `${itemLabel}.control_refs`),
|
|
23
|
+
route_binding_ref: key(row.route_binding_ref, `${itemLabel}.route_binding_ref`),
|
|
24
|
+
component_binding_refs: keys(row.component_binding_refs, `${itemLabel}.component_binding_refs`),
|
|
25
|
+
root_journey_check_ref: key(row.root_journey_check_ref, `${itemLabel}.root_journey_check_ref`),
|
|
26
|
+
entry_action_ref: key(row.entry_action_ref, `${itemLabel}.entry_action_ref`),
|
|
27
|
+
design_targets: parseDesignTargets(row.design_targets, `${itemLabel}.design_targets`),
|
|
28
|
+
acceptance_blockers: parseAcceptanceBlockers(row.acceptance_blockers, `${itemLabel}.acceptance_blockers`),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function parseDesignTargets(value, label) {
|
|
33
|
+
return array(value, label).map((item, index) => {
|
|
34
|
+
const itemLabel = `${label}[${index}]`;
|
|
35
|
+
const row = object(item, itemLabel, [
|
|
36
|
+
"key",
|
|
37
|
+
"interpretation",
|
|
38
|
+
"source_paths",
|
|
39
|
+
"condition_keys",
|
|
40
|
+
"claim_refs",
|
|
41
|
+
"conformance_check_ref",
|
|
42
|
+
"conformance_assertion_ref",
|
|
43
|
+
"verification_method_bindings",
|
|
44
|
+
"actual_artifact_path",
|
|
45
|
+
"comparison_artifact_path",
|
|
46
|
+
]);
|
|
47
|
+
return {
|
|
48
|
+
key: key(row.key, `${itemLabel}.key`),
|
|
49
|
+
interpretation: literal(row.interpretation, ["exact_target", "constraint"], `${itemLabel}.interpretation`),
|
|
50
|
+
source_paths: repositoryFiles(row.source_paths, `${itemLabel}.source_paths`),
|
|
51
|
+
condition_keys: keys(row.condition_keys, `${itemLabel}.condition_keys`),
|
|
52
|
+
claim_refs: strings(row.claim_refs, `${itemLabel}.claim_refs`),
|
|
53
|
+
conformance_check_ref: key(row.conformance_check_ref, `${itemLabel}.conformance_check_ref`),
|
|
54
|
+
conformance_assertion_ref: key(row.conformance_assertion_ref, `${itemLabel}.conformance_assertion_ref`),
|
|
55
|
+
verification_method_bindings: parseVerificationMethodBindings(row.verification_method_bindings, `${itemLabel}.verification_method_bindings`),
|
|
56
|
+
actual_artifact_path: repositoryFile(row.actual_artifact_path, `${itemLabel}.actual_artifact_path`),
|
|
57
|
+
comparison_artifact_path: repositoryFile(row.comparison_artifact_path, `${itemLabel}.comparison_artifact_path`),
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function parseAcceptanceBlockers(value, label) {
|
|
62
|
+
return array(value, label).map((item, index) => {
|
|
63
|
+
const itemLabel = `${label}[${index}]`;
|
|
64
|
+
const row = object(item, itemLabel, [
|
|
65
|
+
"key",
|
|
66
|
+
"status",
|
|
67
|
+
"refs",
|
|
68
|
+
"source_item_refs",
|
|
69
|
+
"verification_methods",
|
|
70
|
+
"rationale",
|
|
71
|
+
]);
|
|
72
|
+
return {
|
|
73
|
+
key: key(row.key, `${itemLabel}.key`),
|
|
74
|
+
status: literal(row.status, ["machine_claim", "external_confirmation"], `${itemLabel}.status`),
|
|
75
|
+
refs: strings(row.refs, `${itemLabel}.refs`),
|
|
76
|
+
source_item_refs: strings(row.source_item_refs, `${itemLabel}.source_item_refs`),
|
|
77
|
+
verification_methods: array(row.verification_methods, `${itemLabel}.verification_methods`).map((method, methodIndex) => literal(method, DESIGN_RESOURCE_VERIFICATION_METHODS, `${itemLabel}.verification_methods[${methodIndex}]`)),
|
|
78
|
+
rationale: string(row.rationale, `${itemLabel}.rationale`),
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function parseVerificationMethodBindings(value, label) {
|
|
83
|
+
return array(value, label).map((item, index) => {
|
|
84
|
+
const itemLabel = `${label}[${index}]`;
|
|
85
|
+
const row = object(item, itemLabel, ["method", "assertion_ref"]);
|
|
86
|
+
return {
|
|
87
|
+
method: literal(row.method, DESIGN_RESOURCE_VERIFICATION_METHODS, `${itemLabel}.method`),
|
|
88
|
+
assertion_ref: key(row.assertion_ref, `${itemLabel}.assertion_ref`),
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function keys(value, label) {
|
|
93
|
+
return array(value, label).map((item, index) => key(item, `${label}[${index}]`));
|
|
94
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DesignResourceVerificationMethod } from "./design-resource-handoff-types.js";
|
|
2
|
+
export type DesignTargetInterpretationV2 = "exact_target" | "constraint";
|
|
3
|
+
export interface DeliveryDesignVerificationBindingV2 {
|
|
4
|
+
method: DesignResourceVerificationMethod;
|
|
5
|
+
assertion_ref: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DeliveryDesignTargetV2 {
|
|
8
|
+
key: string;
|
|
9
|
+
interpretation: DesignTargetInterpretationV2;
|
|
10
|
+
source_paths: string[];
|
|
11
|
+
condition_keys: string[];
|
|
12
|
+
claim_refs: string[];
|
|
13
|
+
conformance_check_ref: string;
|
|
14
|
+
conformance_assertion_ref: string;
|
|
15
|
+
verification_method_bindings: DeliveryDesignVerificationBindingV2[];
|
|
16
|
+
actual_artifact_path: string;
|
|
17
|
+
comparison_artifact_path: string;
|
|
18
|
+
}
|
|
19
|
+
export type DesignAcceptanceBlockerStatusV2 = "machine_claim" | "external_confirmation";
|
|
20
|
+
export interface DeliveryDesignAcceptanceBlockerV2 {
|
|
21
|
+
key: string;
|
|
22
|
+
status: DesignAcceptanceBlockerStatusV2;
|
|
23
|
+
refs: string[];
|
|
24
|
+
source_item_refs: string[];
|
|
25
|
+
verification_methods: DesignResourceVerificationMethod[];
|
|
26
|
+
rationale: string;
|
|
27
|
+
}
|
|
28
|
+
export interface DeliverySurfaceBindingV2 {
|
|
29
|
+
key: string;
|
|
30
|
+
surface_ref: string;
|
|
31
|
+
target_ref: string;
|
|
32
|
+
control_refs: string[];
|
|
33
|
+
route_binding_ref: string;
|
|
34
|
+
component_binding_refs: string[];
|
|
35
|
+
root_journey_check_ref: string;
|
|
36
|
+
entry_action_ref: string;
|
|
37
|
+
design_targets: DeliveryDesignTargetV2[];
|
|
38
|
+
acceptance_blockers: DeliveryDesignAcceptanceBlockerV2[];
|
|
39
|
+
}
|
|
40
|
+
export interface CompiledDesignTargetV2 extends DeliveryDesignTargetV2 {
|
|
41
|
+
surface_binding_ref: string;
|
|
42
|
+
surface_ref: string;
|
|
43
|
+
target_ref: string;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CompiledClaimsV2 } from "./long-task-claims.js";
|
|
2
|
+
import type { DeliveryCheckV2, DeliveryOutcomeV2, ProductClaimV2, ProofSurface } from "./long-task-delivery-types.js";
|
|
3
|
+
export type Reporter = (message: string) => void;
|
|
4
|
+
export declare function bindingCarriers(routeRef: string, componentRefs: string[], bindings: Map<string, DeliveryOutcomeV2["technical"]["bindings"][number]>, label: string, report?: Reporter): string[];
|
|
5
|
+
export declare function validateRootJourney(binding: DeliveryOutcomeV2["product"]["surface_bindings"][number], check: DeliveryCheckV2, label: string, report?: Reporter): void;
|
|
6
|
+
export declare function validateTargetLocalClaimProof(outcome: DeliveryOutcomeV2, claim: ProductClaimV2, targetRef: string, expectedSurface: ProofSurface | null, claims: CompiledClaimsV2, checks: Map<string, DeliveryCheckV2>, label: string, report?: Reporter): void;
|
|
7
|
+
export declare function expectedControlProofSurface(runtimeFamily: string | undefined): ProofSurface;
|
|
8
|
+
export declare function controlClaims(claims: Map<string, ProductClaimV2>, controlRef: string): ProductClaimV2[];
|
|
9
|
+
export declare function validateCarrierInputs(check: DeliveryCheckV2, carriers: string[], label: string, report?: Reporter): void;
|
|
10
|
+
export declare function unique(values: string[], code: string, detail: string, report?: Reporter): void;
|
|
11
|
+
export declare function issue(report: Reporter | undefined, code: string, detail: string): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { proveRepositoryPatternSubset } from "./long-task-paths.js";
|
|
2
|
+
export function bindingCarriers(routeRef, componentRefs, bindings, label, report) {
|
|
3
|
+
if (!componentRefs.length)
|
|
4
|
+
issue(report, "ui_surface_binding_component_ref_required", label);
|
|
5
|
+
unique(componentRefs, "ui_surface_binding_component_ref_duplicate", label, report);
|
|
6
|
+
const carriers = [];
|
|
7
|
+
for (const ref of [routeRef, ...componentRefs]) {
|
|
8
|
+
const binding = bindings.get(ref);
|
|
9
|
+
if (!binding) {
|
|
10
|
+
issue(report, "ui_surface_binding_technical_binding_unknown", `${label}:${ref}`);
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (!binding.carrier_paths.length)
|
|
14
|
+
issue(report, "ui_surface_binding_carrier_required", `${label}:${ref}`);
|
|
15
|
+
carriers.push(...binding.carrier_paths);
|
|
16
|
+
}
|
|
17
|
+
return [...new Set(carriers)].sort();
|
|
18
|
+
}
|
|
19
|
+
export function validateRootJourney(binding, check, label, report) {
|
|
20
|
+
if (check.execution_target.target_ref !== binding.target_ref ||
|
|
21
|
+
check.execution_target.entrypoint !== "root")
|
|
22
|
+
issue(report, "ui_surface_binding_root_target_mismatch", label);
|
|
23
|
+
if (!check.journey_roles.includes("success"))
|
|
24
|
+
issue(report, "ui_surface_binding_root_success_required", label);
|
|
25
|
+
if (!check.scenario.when.some((step) => step.key === binding.entry_action_ref))
|
|
26
|
+
issue(report, "ui_surface_binding_entry_action_unknown", `${label}:${binding.entry_action_ref}`);
|
|
27
|
+
}
|
|
28
|
+
export function validateTargetLocalClaimProof(outcome, claim, targetRef, expectedSurface, claims, checks, label, report) {
|
|
29
|
+
const proofs = claims.summary.claims_by_outcome[outcome.key]?.[claim.local_key]?.proofs ??
|
|
30
|
+
[];
|
|
31
|
+
const matched = proofs.some((proof) => {
|
|
32
|
+
const check = checks.get(proof.check_key);
|
|
33
|
+
return (check?.execution_target.target_ref === targetRef &&
|
|
34
|
+
(expectedSurface === null || proof.proof_surface === expectedSurface));
|
|
35
|
+
});
|
|
36
|
+
if (!matched)
|
|
37
|
+
issue(report, "ui_surface_binding_target_claim_proof_missing", `${label}:${claim.local_key}:${targetRef}:${expectedSurface ?? "any"}`);
|
|
38
|
+
}
|
|
39
|
+
export function expectedControlProofSurface(runtimeFamily) {
|
|
40
|
+
return runtimeFamily === "browser" ? "ui_browser" : "runtime_behavior";
|
|
41
|
+
}
|
|
42
|
+
export function controlClaims(claims, controlRef) {
|
|
43
|
+
return [...claims.values()].filter((claim) => claim.kind === "control" &&
|
|
44
|
+
claim.local_key.startsWith(`control.${controlRef}.`));
|
|
45
|
+
}
|
|
46
|
+
export function validateCarrierInputs(check, carriers, label, report) {
|
|
47
|
+
for (const carrier of carriers)
|
|
48
|
+
if (!check.input_paths.some((input) => proveRepositoryPatternSubset(carrier, input).status ===
|
|
49
|
+
"proven_subset"))
|
|
50
|
+
issue(report, "ui_surface_binding_carrier_outside_check_inputs", `${label}:${check.key}:${carrier}`);
|
|
51
|
+
}
|
|
52
|
+
export function unique(values, code, detail, report) {
|
|
53
|
+
if (new Set(values).size !== values.length)
|
|
54
|
+
issue(report, code, detail);
|
|
55
|
+
}
|
|
56
|
+
export function issue(report, code, detail) {
|
|
57
|
+
const message = `delivery_contract_invalid:${code}:${detail}`;
|
|
58
|
+
if (report)
|
|
59
|
+
report(message);
|
|
60
|
+
else
|
|
61
|
+
throw new Error(message);
|
|
62
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { CompiledCheckV2, CompiledDeliveryContractV2 } from "./long-task-delivery-types.js";
|
|
2
|
+
export interface VerificationExecutionPreviewV1 {
|
|
3
|
+
schema_version: "long-task-verification-preview-v1";
|
|
4
|
+
compiled_identity: string;
|
|
5
|
+
authority_revision: number;
|
|
6
|
+
acceptance_authorized: false;
|
|
7
|
+
executes_checks: false;
|
|
8
|
+
writes_progress: false;
|
|
9
|
+
selected_outcome: string | null;
|
|
10
|
+
selected_check: string | null;
|
|
11
|
+
main_raw_executions: MainRawExecutionPreviewV1[];
|
|
12
|
+
counterfactual_executions: CounterfactualExecutionPreviewV1[];
|
|
13
|
+
summary: {
|
|
14
|
+
selected_checks: number;
|
|
15
|
+
unique_main_runner_invocations: number;
|
|
16
|
+
counterfactual_runner_invocation_upper_bound: number;
|
|
17
|
+
declared_runner_invocation_upper_bound: number;
|
|
18
|
+
declared_command_attempt_upper_bound: number;
|
|
19
|
+
};
|
|
20
|
+
limitations: string[];
|
|
21
|
+
}
|
|
22
|
+
interface MainRawExecutionPreviewV1 {
|
|
23
|
+
raw_execution_identity: string;
|
|
24
|
+
check_refs: string[];
|
|
25
|
+
execution_target: CompiledCheckV2["execution_target"];
|
|
26
|
+
execution_target_definition: CompiledCheckV2["execution_target_definition"];
|
|
27
|
+
runner: RunnerPreviewV1;
|
|
28
|
+
environment_requirements: CompiledCheckV2["environment_requirements"];
|
|
29
|
+
}
|
|
30
|
+
interface CounterfactualExecutionPreviewV1 {
|
|
31
|
+
scope: "global" | "outcome";
|
|
32
|
+
outcome_key: string | null;
|
|
33
|
+
control_key: string;
|
|
34
|
+
check_ref: string;
|
|
35
|
+
raw_execution_identity: string;
|
|
36
|
+
mutation: {
|
|
37
|
+
type: "remove_paths";
|
|
38
|
+
paths: string[];
|
|
39
|
+
} | {
|
|
40
|
+
type: "replace_file";
|
|
41
|
+
path: string;
|
|
42
|
+
fixture_path: string;
|
|
43
|
+
};
|
|
44
|
+
runner: RunnerPreviewV1;
|
|
45
|
+
}
|
|
46
|
+
type RunnerPreviewV1 = Pick<CompiledCheckV2["runner"], "type" | "target" | "argv" | "cwd" | "timeout_ms" | "effect" | "retry_policy" | "idempotent" | "resolved_cwd" | "resolved_target" | "definition_sha256">;
|
|
47
|
+
export declare function previewVerificationExecution(workdirInput: string, selection?: {
|
|
48
|
+
outcome?: string;
|
|
49
|
+
check?: string;
|
|
50
|
+
}): Promise<VerificationExecutionPreviewV1>;
|
|
51
|
+
export declare function projectVerificationExecutionPreview(compiled: CompiledDeliveryContractV2, authorityRevision: number, selection?: {
|
|
52
|
+
outcome?: string;
|
|
53
|
+
check?: string;
|
|
54
|
+
}): VerificationExecutionPreviewV1;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { loadActiveLongTaskAuthority } from "./long-task-state.js";
|
|
3
|
+
import { selectChecks } from "./long-task-verifier-v2.js";
|
|
4
|
+
import { repositoryRoot } from "./long-task-workspace.js";
|
|
5
|
+
export async function previewVerificationExecution(workdirInput, selection = {}) {
|
|
6
|
+
const repository = await repositoryRoot(process.cwd());
|
|
7
|
+
const active = (await loadActiveLongTaskAuthority(repository, { migrate_legacy: true })).authority;
|
|
8
|
+
if (!active)
|
|
9
|
+
throw new Error("active_task_missing");
|
|
10
|
+
if (active.workdir !== path.resolve(workdirInput))
|
|
11
|
+
throw new Error("active_task_workdir_mismatch");
|
|
12
|
+
return projectVerificationExecutionPreview(active.authority_snapshot, active.authority_revision, selection);
|
|
13
|
+
}
|
|
14
|
+
export function projectVerificationExecutionPreview(compiled, authorityRevision, selection = {}) {
|
|
15
|
+
const selected = selectChecks(compiled, selection);
|
|
16
|
+
const mainRawExecutions = mainExecutionPreviews(selected);
|
|
17
|
+
const counterfactualExecutions = counterfactualExecutionPreviews(compiled, selected);
|
|
18
|
+
const declaredRunnerInvocationUpperBound = mainRawExecutions.length + counterfactualExecutions.length;
|
|
19
|
+
return {
|
|
20
|
+
schema_version: "long-task-verification-preview-v1",
|
|
21
|
+
compiled_identity: compiled.compiled_identity,
|
|
22
|
+
authority_revision: authorityRevision,
|
|
23
|
+
acceptance_authorized: false,
|
|
24
|
+
executes_checks: false,
|
|
25
|
+
writes_progress: false,
|
|
26
|
+
selected_outcome: selection.outcome ?? null,
|
|
27
|
+
selected_check: selection.check ?? null,
|
|
28
|
+
main_raw_executions: mainRawExecutions,
|
|
29
|
+
counterfactual_executions: counterfactualExecutions,
|
|
30
|
+
summary: {
|
|
31
|
+
selected_checks: selected.length,
|
|
32
|
+
unique_main_runner_invocations: mainRawExecutions.length,
|
|
33
|
+
counterfactual_runner_invocation_upper_bound: counterfactualExecutions.length,
|
|
34
|
+
declared_runner_invocation_upper_bound: declaredRunnerInvocationUpperBound,
|
|
35
|
+
declared_command_attempt_upper_bound: [
|
|
36
|
+
...mainRawExecutions.map((entry) => entry.runner),
|
|
37
|
+
...counterfactualExecutions.map((entry) => entry.runner),
|
|
38
|
+
].reduce((total, runner) => total + maximumAttempts(runner), 0),
|
|
39
|
+
},
|
|
40
|
+
limitations: [
|
|
41
|
+
"This preview does not evaluate current-snapshot pre-run findings; verification may stop before invoking a runner.",
|
|
42
|
+
"Counts describe Harness runner invocations and declared retry attempts, not subprocesses, builds, elapsed time, or work performed internally by a project runner.",
|
|
43
|
+
"The preview is not verification evidence and cannot authorize acceptance.",
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function mainExecutionPreviews(checks) {
|
|
48
|
+
const groups = new Map();
|
|
49
|
+
for (const check of checks) {
|
|
50
|
+
const existing = groups.get(check.raw_execution_identity) ?? [];
|
|
51
|
+
existing.push(check);
|
|
52
|
+
groups.set(check.raw_execution_identity, existing);
|
|
53
|
+
}
|
|
54
|
+
return [...groups.entries()]
|
|
55
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
56
|
+
.map(([rawExecutionIdentity, groupedChecks]) => {
|
|
57
|
+
const check = groupedChecks[0];
|
|
58
|
+
return {
|
|
59
|
+
raw_execution_identity: rawExecutionIdentity,
|
|
60
|
+
check_refs: groupedChecks.map(checkRef).sort(),
|
|
61
|
+
execution_target: check.execution_target,
|
|
62
|
+
execution_target_definition: check.execution_target_definition,
|
|
63
|
+
runner: runnerPreview(check),
|
|
64
|
+
environment_requirements: check.environment_requirements,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function counterfactualExecutionPreviews(compiled, checks) {
|
|
69
|
+
const selected = new Map(checks.map((check) => [checkRef(check), check]));
|
|
70
|
+
const result = [];
|
|
71
|
+
for (const control of compiled.global.acceptance.counterfactual_controls) {
|
|
72
|
+
const check = selected.get(`GLOBAL:${control.check_key}`);
|
|
73
|
+
if (check)
|
|
74
|
+
result.push({
|
|
75
|
+
scope: "global",
|
|
76
|
+
outcome_key: null,
|
|
77
|
+
control_key: control.key,
|
|
78
|
+
check_ref: checkRef(check),
|
|
79
|
+
raw_execution_identity: check.raw_execution_identity,
|
|
80
|
+
mutation: control.mutation,
|
|
81
|
+
runner: runnerPreview(check),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
for (const outcome of compiled.outcomes)
|
|
85
|
+
for (const control of outcome.acceptance.counterfactual_controls) {
|
|
86
|
+
const check = selected.get(`${outcome.key}:${control.check_key}`);
|
|
87
|
+
if (check)
|
|
88
|
+
result.push({
|
|
89
|
+
scope: "outcome",
|
|
90
|
+
outcome_key: outcome.key,
|
|
91
|
+
control_key: control.key,
|
|
92
|
+
check_ref: checkRef(check),
|
|
93
|
+
raw_execution_identity: check.raw_execution_identity,
|
|
94
|
+
mutation: control.mutation,
|
|
95
|
+
runner: runnerPreview(check),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return result.sort((left, right) => `${left.check_ref}:${left.control_key}`.localeCompare(`${right.check_ref}:${right.control_key}`));
|
|
99
|
+
}
|
|
100
|
+
function checkRef(check) {
|
|
101
|
+
return `${check.outcome_key ?? "GLOBAL"}:${check.key}`;
|
|
102
|
+
}
|
|
103
|
+
function runnerPreview(check) {
|
|
104
|
+
return {
|
|
105
|
+
type: check.runner.type,
|
|
106
|
+
target: check.runner.target,
|
|
107
|
+
argv: check.runner.argv,
|
|
108
|
+
cwd: check.runner.cwd,
|
|
109
|
+
timeout_ms: check.runner.timeout_ms,
|
|
110
|
+
effect: check.runner.effect,
|
|
111
|
+
retry_policy: check.runner.retry_policy,
|
|
112
|
+
idempotent: check.runner.idempotent,
|
|
113
|
+
resolved_cwd: check.runner.resolved_cwd,
|
|
114
|
+
resolved_target: check.runner.resolved_target,
|
|
115
|
+
definition_sha256: check.runner.definition_sha256,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function maximumAttempts(runner) {
|
|
119
|
+
return runner.retry_policy === "transient_once" ? 2 : 1;
|
|
120
|
+
}
|
|
@@ -3,10 +3,11 @@ import { assertVerifierAuthorityCurrent } from "./long-task-freshness.js";
|
|
|
3
3
|
import { enrichCheckResultFindings, enrichFinding, } from "./long-task-finding-context.js";
|
|
4
4
|
import { executeCheckRunner } from "./long-task-check-runner.js";
|
|
5
5
|
import { evaluateCheckEvidence, evaluateGlobalCounterfactuals, evaluateOutcomeCounterfactuals, } from "./long-task-evidence-v2.js";
|
|
6
|
-
import {
|
|
6
|
+
import { matchesRepoPattern } from "./long-task-paths.js";
|
|
7
7
|
import { activeAuthorityIdentityMatches, loadActiveLongTaskAuthority, writeProgressRecord, } from "./long-task-state.js";
|
|
8
8
|
import { createProgressRecord } from "./long-task-progress.js";
|
|
9
9
|
import { changedWorkspacePaths, createWorkspaceSnapshot, repositoryRoot, } from "./long-task-workspace.js";
|
|
10
|
+
import { classifyWorkspaceScope, protectedWorkspacePaths, } from "./long-task-workspace-scope.js";
|
|
10
11
|
export async function verifyDeliveryContract(workdir, selection = {}) {
|
|
11
12
|
const repository = await repositoryRoot(process.cwd());
|
|
12
13
|
const active = (await loadActiveLongTaskAuthority(repository, { migrate_legacy: true })).authority;
|
|
@@ -235,29 +236,21 @@ async function preRunFindings(compiled, current) {
|
|
|
235
236
|
message: "A compiled Contract input changed.",
|
|
236
237
|
next_action: "Run ty-context long-task compile --revise after reviewing the Contract change.",
|
|
237
238
|
}));
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
...outcome.technical.expected_change_paths,
|
|
247
|
-
...outcome.technical.allowed_support_paths,
|
|
248
|
-
]);
|
|
249
|
-
const forbidden = [
|
|
250
|
-
...compiled.global.technical.forbidden_paths.map((entry) => entry.path),
|
|
251
|
-
...compiled.outcomes.flatMap((outcome) => outcome.technical.forbidden_paths),
|
|
252
|
-
];
|
|
253
|
-
const escaped = findScopeEscapes(changed, allowed, forbidden);
|
|
239
|
+
const changed = changedWorkspacePaths(compiled.initial_task_base.workspace_manifest, current);
|
|
240
|
+
const classification = classifyWorkspaceScope(compiled, changed, protectedWorkspacePaths({
|
|
241
|
+
contract_files: compiled.contract_files,
|
|
242
|
+
source_hashes: compiled.source_hashes,
|
|
243
|
+
context_hashes: compiled.context_snapshot.sha256,
|
|
244
|
+
checks: allCompiledChecks(compiled),
|
|
245
|
+
}));
|
|
246
|
+
const escaped = classification.blocking_paths;
|
|
254
247
|
return escaped.length
|
|
255
248
|
? [
|
|
256
249
|
{
|
|
257
250
|
code: "scope_escape",
|
|
258
251
|
outcome_key: null,
|
|
259
252
|
check_key: null,
|
|
260
|
-
message: `Changed paths
|
|
253
|
+
message: `Changed paths escape the Contract boundary (forbidden: ${classification.forbidden.join(",") || "none"}; unclassified: ${classification.unclassified.join(",") || "none"}).`,
|
|
261
254
|
actual: escaped,
|
|
262
255
|
next_action: "Review risk/ownership, revise declared change paths and recompile in the same Goal.",
|
|
263
256
|
},
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
interface WorkspaceScopeAuthority {
|
|
2
|
+
global: {
|
|
3
|
+
technical: {
|
|
4
|
+
forbidden_paths: Array<{
|
|
5
|
+
path: string;
|
|
6
|
+
}>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
outcomes: Array<{
|
|
10
|
+
technical: {
|
|
11
|
+
expected_change_paths: string[];
|
|
12
|
+
allowed_support_paths: string[];
|
|
13
|
+
forbidden_paths: string[];
|
|
14
|
+
};
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export interface WorkspaceScopeClassificationV2 {
|
|
18
|
+
protected: string[];
|
|
19
|
+
expected_change: string[];
|
|
20
|
+
allowed_support: string[];
|
|
21
|
+
forbidden: string[];
|
|
22
|
+
unclassified: string[];
|
|
23
|
+
blocking_paths: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare function classifyWorkspaceScope(authority: WorkspaceScopeAuthority, changedPaths: string[], protectedPaths: string[]): WorkspaceScopeClassificationV2;
|
|
26
|
+
export declare function protectedWorkspacePaths(input: {
|
|
27
|
+
contract_files?: Record<string, string> | null;
|
|
28
|
+
source_hashes?: Record<string, string> | null;
|
|
29
|
+
context_hashes?: Record<string, string> | null;
|
|
30
|
+
checks?: Array<{
|
|
31
|
+
verification_input_hashes: Record<string, string>;
|
|
32
|
+
}>;
|
|
33
|
+
additional_files?: string[];
|
|
34
|
+
}): string[];
|
|
35
|
+
export declare function firstLockManagedWorkspacePaths(repository: string, changedPaths: string[]): Promise<string[]>;
|
|
36
|
+
export declare function workspaceScopeErrors(classification: WorkspaceScopeClassificationV2): string[];
|
|
37
|
+
export declare function assertWorkspaceScope(classification: WorkspaceScopeClassificationV2): void;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readConfig } from "./config.js";
|
|
3
|
+
import { harnessConfigPath, harnessPath, harnessRoot } from "./harness-root.js";
|
|
4
|
+
import { listFiles, pathExists } from "./fs.js";
|
|
5
|
+
import { matchesRepoPattern, normalizeRepositoryFile, } from "./long-task-paths.js";
|
|
6
|
+
import { packageAssetPath } from "./paths.js";
|
|
7
|
+
import { enabledManagedSkillNames } from "./profiles.js";
|
|
8
|
+
export function classifyWorkspaceScope(authority, changedPaths, protectedPaths) {
|
|
9
|
+
const protectedSet = new Set(normalizeFiles(protectedPaths));
|
|
10
|
+
const expectedPatterns = authority.outcomes.flatMap((outcome) => outcome.technical.expected_change_paths);
|
|
11
|
+
const supportPatterns = authority.outcomes.flatMap((outcome) => outcome.technical.allowed_support_paths);
|
|
12
|
+
const forbiddenPatterns = [
|
|
13
|
+
...authority.global.technical.forbidden_paths.map((entry) => entry.path),
|
|
14
|
+
...authority.outcomes.flatMap((outcome) => outcome.technical.forbidden_paths),
|
|
15
|
+
];
|
|
16
|
+
const result = {
|
|
17
|
+
protected: [],
|
|
18
|
+
expected_change: [],
|
|
19
|
+
allowed_support: [],
|
|
20
|
+
forbidden: [],
|
|
21
|
+
unclassified: [],
|
|
22
|
+
blocking_paths: [],
|
|
23
|
+
};
|
|
24
|
+
for (const file of normalizeFiles(changedPaths)) {
|
|
25
|
+
if (protectedSet.has(file))
|
|
26
|
+
result.protected.push(file);
|
|
27
|
+
else if (matchesAny(file, forbiddenPatterns))
|
|
28
|
+
result.forbidden.push(file);
|
|
29
|
+
else if (matchesAny(file, expectedPatterns))
|
|
30
|
+
result.expected_change.push(file);
|
|
31
|
+
else if (matchesAny(file, supportPatterns))
|
|
32
|
+
result.allowed_support.push(file);
|
|
33
|
+
else
|
|
34
|
+
result.unclassified.push(file);
|
|
35
|
+
}
|
|
36
|
+
result.blocking_paths = [...result.forbidden, ...result.unclassified].sort();
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
export function protectedWorkspacePaths(input) {
|
|
40
|
+
return normalizeFiles([
|
|
41
|
+
...Object.keys(input.contract_files ?? {}),
|
|
42
|
+
...Object.keys(input.source_hashes ?? {}),
|
|
43
|
+
...Object.keys(input.context_hashes ?? {}),
|
|
44
|
+
...(input.checks ?? []).flatMap((check) => Object.keys(check.verification_input_hashes)),
|
|
45
|
+
...(input.additional_files ?? []),
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
export async function firstLockManagedWorkspacePaths(repository, changedPaths) {
|
|
49
|
+
const root = await harnessRoot(repository);
|
|
50
|
+
const config = await readConfig(repository);
|
|
51
|
+
const managedFiles = new Set([
|
|
52
|
+
await harnessConfigPath(repository),
|
|
53
|
+
".codex/hooks.json",
|
|
54
|
+
...(await packageManagedBootstrapFiles(root, config)),
|
|
55
|
+
].map(normalizeManagedRoot));
|
|
56
|
+
return normalizeFiles(changedPaths).filter((file) => managedFiles.has(file));
|
|
57
|
+
}
|
|
58
|
+
export function workspaceScopeErrors(classification) {
|
|
59
|
+
return [
|
|
60
|
+
...classification.forbidden.map((file) => `workspace_path_forbidden:${file}`),
|
|
61
|
+
...classification.unclassified.map((file) => `workspace_path_unclassified:${file}`),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
export function assertWorkspaceScope(classification) {
|
|
65
|
+
const [error] = workspaceScopeErrors(classification);
|
|
66
|
+
if (error)
|
|
67
|
+
throw new Error(error);
|
|
68
|
+
}
|
|
69
|
+
function normalizeFiles(files) {
|
|
70
|
+
return [
|
|
71
|
+
...new Set(files.map((file) => normalizeRepositoryFile(file))),
|
|
72
|
+
].sort();
|
|
73
|
+
}
|
|
74
|
+
function matchesAny(file, patterns) {
|
|
75
|
+
return patterns.some((pattern) => matchesRepoPattern(file, pattern));
|
|
76
|
+
}
|
|
77
|
+
function normalizeManagedRoot(file) {
|
|
78
|
+
return normalizeRepositoryFile(file.replace(/\/+$/u, ""));
|
|
79
|
+
}
|
|
80
|
+
async function packageManagedBootstrapFiles(root, config) {
|
|
81
|
+
const files = [];
|
|
82
|
+
for (const managed of config.managed_files)
|
|
83
|
+
files.push(...(await managedBootstrapFiles(root, config, managed)));
|
|
84
|
+
return files;
|
|
85
|
+
}
|
|
86
|
+
async function managedBootstrapFiles(root, config, managed) {
|
|
87
|
+
const normalized = normalizeManagedRoot(managed.path);
|
|
88
|
+
if (managed.path === "AGENTS.md" ||
|
|
89
|
+
managed.path === "Makefile" ||
|
|
90
|
+
managed.path === ".github/workflows/harness.yml")
|
|
91
|
+
return [managed.path];
|
|
92
|
+
if (isSkillsManagedPath(normalized, root)) {
|
|
93
|
+
const files = [];
|
|
94
|
+
for (const name of enabledManagedSkillNames(config))
|
|
95
|
+
files.push(...(await assetTreeFiles(harnessPath(root, "skills", name), "skills", name)));
|
|
96
|
+
return files;
|
|
97
|
+
}
|
|
98
|
+
if (normalized === harnessPath(root, "ty-context-managed", "context_templates"))
|
|
99
|
+
return assetTreeFiles(managed.path, "context_templates");
|
|
100
|
+
if (normalized === harnessPath(root, "ty-context-managed", "templates"))
|
|
101
|
+
return assetTreeFiles(managed.path, "templates");
|
|
102
|
+
if (normalized === harnessPath(root, "ty-context-managed", "policies"))
|
|
103
|
+
return assetTreeFiles(managed.path, "policies");
|
|
104
|
+
if (normalized ===
|
|
105
|
+
harnessPath(root, "ty-context-managed", "make", "ty-context.mk"))
|
|
106
|
+
return [managed.path];
|
|
107
|
+
if (managed.path === "tools")
|
|
108
|
+
return assetTreeFiles(managed.path, "tools");
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
async function assetTreeFiles(destinationRoot, ...assetSegments) {
|
|
112
|
+
const sourceRoot = packageAssetPath(...assetSegments);
|
|
113
|
+
if (!(await pathExists(sourceRoot)))
|
|
114
|
+
return [];
|
|
115
|
+
return (await listFiles(sourceRoot)).map((file) => normalizeManagedRoot(harnessPath(destinationRoot, path.relative(sourceRoot, file).replace(/\\/gu, "/"))));
|
|
116
|
+
}
|
|
117
|
+
function isSkillsManagedPath(managedPath, root) {
|
|
118
|
+
return (managedPath === harnessPath(root, "skills") ||
|
|
119
|
+
managedPath === ".harness/agents/skills" ||
|
|
120
|
+
(managedPath === ".agents/skills" && root !== ".agents"));
|
|
121
|
+
}
|
|
@@ -11,6 +11,7 @@ export declare function captureWorkspaceFingerprint(rootInput: string, excludedP
|
|
|
11
11
|
export declare function captureWorkspaceManifest(rootInput: string, workdirInput: string, _copyRoot?: string, additionalExcludedWorkdirs?: string[]): Promise<WorkspaceManifestV2>;
|
|
12
12
|
export declare function createWorkspaceSnapshot(rootInput: string, workdirInput: string, label: string, additionalExcludedWorkdirs?: string[]): Promise<WorkspaceSnapshotV2>;
|
|
13
13
|
export declare function changedWorkspacePaths(baseline: WorkspaceManifestV2, current: WorkspaceManifestV2): string[];
|
|
14
|
+
export declare function changedWorkspacePathsFromHead(rootInput: string, workdirInput: string, additionalExcludedWorkdirs?: string[]): Promise<string[]>;
|
|
14
15
|
export declare function currentGitState(root: string): Promise<{
|
|
15
16
|
head: string;
|
|
16
17
|
tree: string;
|