fix: preserve string and table Profile scope authoring (T-710)
Resolve MR sequence 5 profile_authoring_rejects_valid_string_scope_intents. Decodal 0.4 has no union constraint: retain an opaque scope range with non-materialized table completion hints so string intents remain valid. Keep shared Backend semantic validation authoritative for scope forms/types/unknown keys without changing persisted values or weakening worker/feature editor diagnostics.
Prove actual-provider native/WASM scalar/table, inline/import/patch, nested intent/deny_write/symlink_policy completion and evaluation invariance. Add real save/projection/Runtime scope equivalence and invalid-scope save non-loss coverage. Regenerated WASM artifact is byte-identical; the changed shape is transported via the fingerprint-bound Backend schema metadata.
Validation: root cargo check; config-source39; value_profiles4; unfiltered server643+11; worker-runtime340+17+17; server-api --features typescript77; wasm32 release/wasm-bindgen0.2.117/Binaryen132 -Oz; Deno39; deno task check0/0; fmt/diff checks. Logs target/t710-scope-{check,server,server-api,runtime}.log. No target/ref integration changes.
This commit is contained in:
@@ -569,6 +569,93 @@ Deno.test("generated WASM authors value-based Profiles using the Backend schema
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const field of ["scope", "delegation_scope"]) {
|
||||
for (
|
||||
const [prefix, label] of [["int", "intent"], ["deny", "deny_write"], [
|
||||
"sym",
|
||||
"symlink_policy",
|
||||
]]
|
||||
) {
|
||||
const body =
|
||||
`{ profile.entries = [{ profile.${field} = { ${prefix} } }]; } as WorkspaceConfigSchema`;
|
||||
const cursor = body.lastIndexOf(prefix) + prefix.length;
|
||||
const result = complete_current("main.dcdl", body, cursor, true) as {
|
||||
items: Array<{ label: string }>;
|
||||
};
|
||||
assertEquals(
|
||||
result.items.some((item) => item.label === label),
|
||||
true,
|
||||
`${field}.${label}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
for (
|
||||
const [recipe, expected] of [
|
||||
['{ scope = "workspace_read"; delegation_scope = "workspace_write"; }', {
|
||||
scope: "workspace_read",
|
||||
delegation_scope: "workspace_write",
|
||||
}],
|
||||
['{ scope = "workspace_write"; delegation_scope = "workspace_read"; }', {
|
||||
scope: "workspace_write",
|
||||
delegation_scope: "workspace_read",
|
||||
}],
|
||||
[
|
||||
'{ scope = { intent = "workspace_read"; }; delegation_scope = { intent = "workspace_write"; deny_write = ["private"]; symlink_policy = "resolved"; }; }',
|
||||
{
|
||||
scope: { intent: "workspace_read" },
|
||||
delegation_scope: {
|
||||
intent: "workspace_write",
|
||||
deny_write: ["private"],
|
||||
symlink_policy: "resolved",
|
||||
},
|
||||
},
|
||||
],
|
||||
] as const
|
||||
) {
|
||||
for (
|
||||
const form of [
|
||||
recipe,
|
||||
'import "./scoped.dcdl"',
|
||||
'(import "./scoped.dcdl") // { description = "patched"; }',
|
||||
]
|
||||
) {
|
||||
const scopedContent = content.replace(
|
||||
"profile = {};",
|
||||
`profile = ${form};`,
|
||||
);
|
||||
const scopedTree = {
|
||||
...tree,
|
||||
entries: {
|
||||
"main.dcdl": {
|
||||
...tree.entries["main.dcdl"],
|
||||
content: scopedContent,
|
||||
content_digest: await digestText(scopedContent),
|
||||
},
|
||||
"scoped.dcdl": {
|
||||
path: "scoped.dcdl",
|
||||
content_type: "decodal",
|
||||
content: recipe,
|
||||
content_digest: await digestText(recipe),
|
||||
},
|
||||
},
|
||||
};
|
||||
assertEquals(
|
||||
analyze_snapshot(scopedTree, "main.dcdl", undefined),
|
||||
[],
|
||||
form,
|
||||
);
|
||||
const result = evaluate_snapshot(
|
||||
scopedTree,
|
||||
valueContract,
|
||||
) as typeof evaluated;
|
||||
assertEquals(
|
||||
result.projections[0].data_json.profile.entries[0].profile,
|
||||
form.includes("patched")
|
||||
? { ...expected, description: "patched" }
|
||||
: expected,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Neither completion nor diagnostic shape checking changes the saved value.
|
||||
assertEquals(evaluate_snapshot(tree, valueContract), evaluated);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user