@intentius/chant-lexicon-cedar 0.44.8 → 0.44.10
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 +106 -2
- package/dist/agentcore/embed.d.ts +189 -0
- package/dist/agentcore/embed.d.ts.map +1 -0
- package/dist/agentcore/enforcement.d.ts +76 -0
- package/dist/agentcore/enforcement.d.ts.map +1 -0
- package/dist/agentcore/scan.d.ts +46 -0
- package/dist/agentcore/scan.d.ts.map +1 -0
- package/dist/codegen/docs-dogwood.d.ts +21 -0
- package/dist/codegen/docs-dogwood.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/package.d.ts.map +1 -1
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/dogwood/cli.d.ts +247 -0
- package/dist/dogwood/cli.d.ts.map +1 -0
- package/dist/dogwood/event-schema.d.ts +161 -0
- package/dist/dogwood/event-schema.d.ts.map +1 -0
- package/dist/dogwood/index.d.ts +39 -0
- package/dist/dogwood/index.d.ts.map +1 -0
- package/dist/dogwood/macros.d.ts +96 -0
- package/dist/dogwood/macros.d.ts.map +1 -0
- package/dist/dogwood/policy.d.ts +120 -0
- package/dist/dogwood/policy.d.ts.map +1 -0
- package/dist/dogwood/replay-activity.d.ts +196 -0
- package/dist/dogwood/replay-activity.d.ts.map +1 -0
- package/dist/dogwood/replay-op.d.ts +165 -0
- package/dist/dogwood/replay-op.d.ts.map +1 -0
- package/dist/dogwood/scan.d.ts +109 -0
- package/dist/dogwood/scan.d.ts.map +1 -0
- package/dist/dogwood/serialize.d.ts +66 -0
- package/dist/dogwood/serialize.d.ts.map +1 -0
- package/dist/dogwood/temporal.d.ts +259 -0
- package/dist/dogwood/temporal.d.ts.map +1 -0
- package/dist/dogwood/trace.d.ts +215 -0
- package/dist/dogwood/trace.d.ts.map +1 -0
- package/dist/dogwood/upstream.d.ts +41 -0
- package/dist/dogwood/upstream.d.ts.map +1 -0
- package/dist/dogwood/window.d.ts +73 -0
- package/dist/dogwood/window.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +15 -3
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/post-synth/dogwood-helpers.d.ts +63 -0
- package/dist/lint/post-synth/dogwood-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/dwdc010.d.ts +25 -0
- package/dist/lint/post-synth/dwdc010.d.ts.map +1 -0
- package/dist/lint/post-synth/dwdc011.d.ts +19 -0
- package/dist/lint/post-synth/dwdc011.d.ts.map +1 -0
- package/dist/lint/post-synth/dwdc012.d.ts +21 -0
- package/dist/lint/post-synth/dwdc012.d.ts.map +1 -0
- package/dist/lint/post-synth/dwdc013.d.ts +33 -0
- package/dist/lint/post-synth/dwdc013.d.ts.map +1 -0
- package/dist/lint/post-synth/dwde010.d.ts +32 -0
- package/dist/lint/post-synth/dwde010.d.ts.map +1 -0
- package/dist/lint/post-synth/dwde011.d.ts +33 -0
- package/dist/lint/post-synth/dwde011.d.ts.map +1 -0
- package/dist/lint/post-synth/dwds010.d.ts +24 -0
- package/dist/lint/post-synth/dwds010.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/okf/index.md +7 -0
- package/dist/okf/rules/DWDC010.md +11 -0
- package/dist/okf/rules/DWDC011.md +11 -0
- package/dist/okf/rules/DWDC012.md +11 -0
- package/dist/okf/rules/DWDC013.md +15 -0
- package/dist/okf/rules/DWDE010.md +11 -0
- package/dist/okf/rules/DWDE011.md +11 -0
- package/dist/okf/rules/DWDS010.md +11 -0
- package/dist/okf/types/Policy.md +1 -0
- package/dist/op/activities/index.d.ts +18 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/policy-text.d.ts +53 -0
- package/dist/policy-text.d.ts.map +1 -0
- package/dist/rules/dogwood-helpers.ts +139 -0
- package/dist/rules/dwdc010.ts +62 -0
- package/dist/rules/dwdc011.ts +61 -0
- package/dist/rules/dwdc012.ts +46 -0
- package/dist/rules/dwdc013.ts +64 -0
- package/dist/rules/dwde010.ts +130 -0
- package/dist/rules/dwde011.ts +108 -0
- package/dist/rules/dwds010.ts +46 -0
- package/dist/serializer.d.ts +10 -18
- package/dist/serializer.d.ts.map +1 -1
- package/dist/skills/chant-cedar-authoring.md +180 -0
- package/dist/skills/chant-cedar-avp-embedding.md +125 -0
- package/dist/skills/chant-cedar-dogwood.md +327 -0
- package/dist/skills/chant-cedar-meta-policy.md +119 -0
- package/package.json +7 -2
- package/src/agentcore/embed.test.ts +254 -0
- package/src/agentcore/embed.ts +399 -0
- package/src/agentcore/enforcement.test.ts +43 -0
- package/src/agentcore/enforcement.ts +92 -0
- package/src/agentcore/scan.ts +119 -0
- package/src/codegen/docs-dogwood.ts +1119 -0
- package/src/codegen/docs.ts +66 -1
- package/src/codegen/package.ts +3 -2
- package/src/config.test.ts +12 -0
- package/src/config.ts +28 -0
- package/src/dogwood/cli.test.ts +513 -0
- package/src/dogwood/cli.ts +666 -0
- package/src/dogwood/event-schema.test.ts +218 -0
- package/src/dogwood/event-schema.ts +318 -0
- package/src/dogwood/index.ts +271 -0
- package/src/dogwood/macros.test.ts +104 -0
- package/src/dogwood/macros.ts +229 -0
- package/src/dogwood/policy.test.ts +94 -0
- package/src/dogwood/policy.ts +141 -0
- package/src/dogwood/replay-activity.test.ts +481 -0
- package/src/dogwood/replay-activity.ts +506 -0
- package/src/dogwood/replay-op.ts +242 -0
- package/src/dogwood/scan.ts +287 -0
- package/src/dogwood/serialize.test.ts +331 -0
- package/src/dogwood/serialize.ts +246 -0
- package/src/dogwood/temporal.test.ts +272 -0
- package/src/dogwood/temporal.ts +592 -0
- package/src/dogwood/testdata/custom-kinds.dwschema +17 -0
- package/src/dogwood/testdata/default-macros.dw +23 -0
- package/src/dogwood/testdata/lowered-read-after-login.json +13 -0
- package/src/dogwood/testdata/max-window-raised.dwschema +25 -0
- package/src/dogwood/testdata/pinned.dwschema +31 -0
- package/src/dogwood/testdata/read-after-login.cedarschema +20 -0
- package/src/dogwood/testdata/read-after-login.dw +17 -0
- package/src/dogwood/testdata/temporal-policies.dw +53 -0
- package/src/dogwood/trace.test.ts +231 -0
- package/src/dogwood/trace.ts +471 -0
- package/src/dogwood/upstream.ts +41 -0
- package/src/dogwood/window.ts +124 -0
- package/src/index.ts +76 -0
- package/src/lint/audit-catalog.ts +64 -0
- package/src/lint/post-synth/dogwood-helpers.ts +139 -0
- package/src/lint/post-synth/dwd-post-synth.test.ts +374 -0
- package/src/lint/post-synth/dwdc010.ts +62 -0
- package/src/lint/post-synth/dwdc011.ts +61 -0
- package/src/lint/post-synth/dwdc012.ts +46 -0
- package/src/lint/post-synth/dwdc013.ts +64 -0
- package/src/lint/post-synth/dwde-post-synth.test.ts +368 -0
- package/src/lint/post-synth/dwde010.ts +130 -0
- package/src/lint/post-synth/dwde011.ts +108 -0
- package/src/lint/post-synth/dwds010.ts +46 -0
- package/src/lint/post-synth/index.ts +14 -0
- package/src/lint/post-synth/post-synth.test.ts +7 -3
- package/src/op/activities/index.ts +27 -0
- package/src/plugin.test.ts +3 -2
- package/src/plugin.ts +30 -0
- package/src/policy-text.ts +128 -0
- package/src/serializer.ts +71 -109
- package/src/skills/chant-cedar-dogwood.md +327 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
AGENTCORE_ENFORCEMENT,
|
|
4
|
+
describeStage,
|
|
5
|
+
enforcementMode,
|
|
6
|
+
enforcementStage,
|
|
7
|
+
isEnforcing,
|
|
8
|
+
} from "./enforcement";
|
|
9
|
+
|
|
10
|
+
describe("EnforcementMode", () => {
|
|
11
|
+
it("carries the two wire values AWS::BedrockAgentCore::Policy declares", () => {
|
|
12
|
+
// The CloudFormation enum, verbatim: ["ACTIVE", "LOG_ONLY"], default ACTIVE.
|
|
13
|
+
expect(Object.values(AGENTCORE_ENFORCEMENT).sort()).toEqual(["ACTIVE", "LOG_ONLY"]);
|
|
14
|
+
expect(AGENTCORE_ENFORCEMENT.logOnly).toBe("LOG_ONLY");
|
|
15
|
+
expect(AGENTCORE_ENFORCEMENT.enforce).toBe("ACTIVE");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("maps a stage onto the wire value", () => {
|
|
19
|
+
expect(enforcementMode("log-only")).toBe("LOG_ONLY");
|
|
20
|
+
expect(enforcementMode("enforce")).toBe("ACTIVE");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("round-trips a stage through the wire value", () => {
|
|
24
|
+
for (const stage of ["log-only", "enforce"] as const) {
|
|
25
|
+
expect(enforcementStage(enforcementMode(stage))).toBe(stage);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("reads an absent EnforcementMode as enforcing, which is AWS's default", () => {
|
|
30
|
+
expect(enforcementStage(undefined)).toBe("enforce");
|
|
31
|
+
expect(isEnforcing(undefined)).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("says which stage reaches the gateway", () => {
|
|
35
|
+
expect(isEnforcing("ACTIVE")).toBe(true);
|
|
36
|
+
expect(isEnforcing("LOG_ONLY")).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("explains a stage the same way everywhere", () => {
|
|
40
|
+
expect(describeStage("log-only")).toMatch(/logged and do not affect the response/);
|
|
41
|
+
expect(describeStage("enforce")).toMatch(/reaches the gateway/);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `EnforcementMode` — the dial that makes a policy rollout observable before it
|
|
3
|
+
* is binding (#1660).
|
|
4
|
+
*
|
|
5
|
+
* `AWS::BedrockAgentCore::Policy` carries an optional `EnforcementMode` with
|
|
6
|
+
* exactly two values, and the CloudFormation schema says what they mean:
|
|
7
|
+
*
|
|
8
|
+
* > Whether the policy contributes to the enforce decision returned to Gateway.
|
|
9
|
+
* > LOG_ONLY policies are still evaluated but their decisions are observed
|
|
10
|
+
* > only, allowing customers to validate a policy against real traffic before
|
|
11
|
+
* > promoting it.
|
|
12
|
+
*
|
|
13
|
+
* That is observe-before-enforce, in the substrate, per policy — the same shape
|
|
14
|
+
* chant already has at the ops layer, and the reason epic #1646 picked
|
|
15
|
+
* AgentCore as the deployment target for the temporal dialect rather than
|
|
16
|
+
* inventing a staging mechanism. A temporal policy is the case that needs it
|
|
17
|
+
* most: `formerly within 24h …` cannot be reasoned about from the source alone,
|
|
18
|
+
* because whether it fires depends on traffic nobody has replayed yet.
|
|
19
|
+
*
|
|
20
|
+
* ### The two names, and why chant does not reuse AWS's
|
|
21
|
+
*
|
|
22
|
+
* The wire values are `LOG_ONLY` and `ACTIVE`. `ACTIVE` is a poor name for
|
|
23
|
+
* "enforcing" — it reads as "not disabled", and `LOG_ONLY` is active too; it is
|
|
24
|
+
* evaluated on every request. So the authoring vocabulary here is
|
|
25
|
+
* `"log-only"` / `"enforce"`, and {@link enforcementMode} is the one place the
|
|
26
|
+
* translation happens. The wire values are exported as well, for a caller that
|
|
27
|
+
* has one in hand from a live read.
|
|
28
|
+
*
|
|
29
|
+
* ### The showcase seam (loomster#171)
|
|
30
|
+
*
|
|
31
|
+
* loomster#171 wants a staged policy rollout it can demonstrate end to end:
|
|
32
|
+
* ship the policy log-only, watch what it would have denied, promote it. This
|
|
33
|
+
* module is that seam. The whole rollout is one argument —
|
|
34
|
+
* `agentCoreStagedPolicy(name, policy, stage)` — so the promotion is a
|
|
35
|
+
* one-token diff a reviewer can see, rather than a hand-edited string in a
|
|
36
|
+
* CloudFormation resource. Anything more elaborate (which environments are
|
|
37
|
+
* promoted, who decides) belongs to the caller's own config; this module's job
|
|
38
|
+
* is to make the two states nameable and the transition legible.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The wire values `EnforcementMode` takes, keyed by the stage they implement.
|
|
43
|
+
*
|
|
44
|
+
* A typed constant pair rather than a bare union so a caller reads
|
|
45
|
+
* `AGENTCORE_ENFORCEMENT.logOnly` at the call site and cannot typo the string.
|
|
46
|
+
*/
|
|
47
|
+
export const AGENTCORE_ENFORCEMENT = {
|
|
48
|
+
/** Evaluated on every request; its decision is observed, never returned. */
|
|
49
|
+
logOnly: "LOG_ONLY",
|
|
50
|
+
/** Contributes to the decision Gateway returns. AWS's own default. */
|
|
51
|
+
enforce: "ACTIVE",
|
|
52
|
+
} as const;
|
|
53
|
+
|
|
54
|
+
/** The `EnforcementMode` property value, as CloudFormation spells it. */
|
|
55
|
+
export type AgentCoreEnforcementMode = (typeof AGENTCORE_ENFORCEMENT)[keyof typeof AGENTCORE_ENFORCEMENT];
|
|
56
|
+
|
|
57
|
+
/** The stage of a rollout, in the vocabulary the seam is authored in. */
|
|
58
|
+
export type AgentCoreStage = "log-only" | "enforce";
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The `EnforcementMode` a stage deploys as.
|
|
62
|
+
*
|
|
63
|
+
* Omitting `EnforcementMode` entirely is legal and means `ACTIVE` — AWS's
|
|
64
|
+
* schema declares that default. This helper never returns `undefined`, so a
|
|
65
|
+
* policy that went through it says which stage it is in on the face of the
|
|
66
|
+
* template, and a diff that promotes one shows the change.
|
|
67
|
+
*/
|
|
68
|
+
export function enforcementMode(stage: AgentCoreStage): AgentCoreEnforcementMode {
|
|
69
|
+
return stage === "log-only" ? AGENTCORE_ENFORCEMENT.logOnly : AGENTCORE_ENFORCEMENT.enforce;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The stage a wire value came from — the inverse of {@link enforcementMode}. */
|
|
73
|
+
export function enforcementStage(mode: AgentCoreEnforcementMode | undefined): AgentCoreStage {
|
|
74
|
+
return mode === AGENTCORE_ENFORCEMENT.logOnly ? "log-only" : "enforce";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** True when the policy's decision reaches Gateway rather than only the log. */
|
|
78
|
+
export function isEnforcing(mode: AgentCoreEnforcementMode | undefined): boolean {
|
|
79
|
+
return enforcementStage(mode) === "enforce";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* One line of prose for a stage, for a description or a plan summary.
|
|
84
|
+
*
|
|
85
|
+
* Kept here rather than at the call sites so every surface that explains a
|
|
86
|
+
* staged policy explains it the same way.
|
|
87
|
+
*/
|
|
88
|
+
export function describeStage(stage: AgentCoreStage): string {
|
|
89
|
+
return stage === "log-only"
|
|
90
|
+
? "Evaluated against real traffic; decisions are logged and do not affect the response."
|
|
91
|
+
: "Enforcing: this policy's decision reaches the gateway.";
|
|
92
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding embedded AgentCore policy statements in a build's emitted output
|
|
3
|
+
* (#1660).
|
|
4
|
+
*
|
|
5
|
+
* The DWD walls read emitted *text* rather than the in-memory model, for the
|
|
6
|
+
* reason `../dogwood/scan.ts` sets out: `chant audit` runs over artifacts chant
|
|
7
|
+
* did not write, and a wall that only fires on chant's own output is not a
|
|
8
|
+
* wall. An embedded statement is the same situation one lexicon further out —
|
|
9
|
+
* the statement lands in whatever the aws lexicon emitted, so this reads the
|
|
10
|
+
* emitted template rather than reaching for a resource class the cedar lexicon
|
|
11
|
+
* deliberately does not import.
|
|
12
|
+
*
|
|
13
|
+
* Structural, not CloudFormation-specific. The thing being looked for is an
|
|
14
|
+
* object with a `Definition.Policy.Statement` string, which is AgentCore's
|
|
15
|
+
* language-agnostic arm wherever it appears — in a CFN template's
|
|
16
|
+
* `Resources.<id>.Properties`, in a plan JSON, in a fixture. The nearest
|
|
17
|
+
* enclosing key is carried along as the name to blame, which for a CFN template
|
|
18
|
+
* is the logical id.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
22
|
+
import { isRecord } from "../policy-text";
|
|
23
|
+
|
|
24
|
+
/** One `Definition.Policy.Statement` found in an emitted artifact. */
|
|
25
|
+
export interface EmbeddedAgentCoreStatement {
|
|
26
|
+
/** The lexicon whose output carried it. */
|
|
27
|
+
lexicon: string;
|
|
28
|
+
/** The filename, or the lexicon's primary output when it had no name. */
|
|
29
|
+
source: string;
|
|
30
|
+
/** The nearest enclosing key — a CloudFormation logical id, in practice. */
|
|
31
|
+
logicalId?: string;
|
|
32
|
+
/** The statement text, verbatim. */
|
|
33
|
+
statement: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The `Cedar` arm as well, for a check that needs to tell the two apart. */
|
|
37
|
+
export interface EmbeddedAgentCoreDefinition extends EmbeddedAgentCoreStatement {
|
|
38
|
+
arm: "Cedar" | "Policy";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function walk(
|
|
42
|
+
node: unknown,
|
|
43
|
+
logicalId: string | undefined,
|
|
44
|
+
found: Array<{ logicalId?: string; arm: "Cedar" | "Policy"; statement: string }>,
|
|
45
|
+
): void {
|
|
46
|
+
if (Array.isArray(node)) {
|
|
47
|
+
for (const item of node) walk(item, logicalId, found);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!isRecord(node)) return;
|
|
51
|
+
|
|
52
|
+
const definition = node.Definition;
|
|
53
|
+
if (isRecord(definition)) {
|
|
54
|
+
for (const arm of ["Cedar", "Policy"] as const) {
|
|
55
|
+
const value = definition[arm];
|
|
56
|
+
if (isRecord(value) && typeof value.Statement === "string") {
|
|
57
|
+
found.push({ ...(logicalId ? { logicalId } : {}), arm, statement: value.Statement });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const [key, value] of Object.entries(node)) {
|
|
63
|
+
// `Properties` is CloudFormation's own wrapper, so it is not the name to
|
|
64
|
+
// blame — the logical id one level up is.
|
|
65
|
+
walk(value, key === "Properties" ? logicalId : key, found);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Every emitted text in a build, with the lexicon and filename that carried it. */
|
|
70
|
+
function emittedTexts(ctx: PostSynthContext): Array<{ lexicon: string; source: string; text: string }> {
|
|
71
|
+
const out: Array<{ lexicon: string; source: string; text: string }> = [];
|
|
72
|
+
for (const [lexicon, output] of ctx.outputs) {
|
|
73
|
+
if (typeof output === "string") {
|
|
74
|
+
if (output.length > 0) out.push({ lexicon, source: lexicon, text: output });
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (typeof output.primary === "string" && output.primary.length > 0) {
|
|
78
|
+
out.push({ lexicon, source: lexicon, text: output.primary });
|
|
79
|
+
}
|
|
80
|
+
for (const [filename, content] of Object.entries(output.files ?? {})) {
|
|
81
|
+
if (typeof content === "string") out.push({ lexicon, source: filename, text: content });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Every AgentCore policy definition embedded in a build's emitted output.
|
|
89
|
+
*
|
|
90
|
+
* Non-JSON output is skipped rather than reported: most emitted files are not
|
|
91
|
+
* JSON, and a parse failure here says nothing about whether a statement is
|
|
92
|
+
* there.
|
|
93
|
+
*/
|
|
94
|
+
export function embeddedAgentCoreDefinitions(ctx: PostSynthContext): EmbeddedAgentCoreDefinition[] {
|
|
95
|
+
const results: EmbeddedAgentCoreDefinition[] = [];
|
|
96
|
+
|
|
97
|
+
for (const { lexicon, source, text } of emittedTexts(ctx)) {
|
|
98
|
+
const trimmed = text.trimStart();
|
|
99
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) continue;
|
|
100
|
+
|
|
101
|
+
let parsed: unknown;
|
|
102
|
+
try {
|
|
103
|
+
parsed = JSON.parse(text);
|
|
104
|
+
} catch {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const found: Array<{ logicalId?: string; arm: "Cedar" | "Policy"; statement: string }> = [];
|
|
109
|
+
walk(parsed, undefined, found);
|
|
110
|
+
for (const hit of found) results.push({ lexicon, source, ...hit });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Only the language-agnostic arm — the one a `.dw` statement travels in. */
|
|
117
|
+
export function embeddedAgentCorePolicyStatements(ctx: PostSynthContext): EmbeddedAgentCoreStatement[] {
|
|
118
|
+
return embeddedAgentCoreDefinitions(ctx).filter((d) => d.arm === "Policy");
|
|
119
|
+
}
|