agent-charley-cli --verbose plan --file /dev/null 2>&1 | head -5
You should see your base URL and key prefix in the output. If you get 401, the key is wrong or expired.A simpler smoke test — pull current server policies:
The device agent polls for policy updates periodically. After applying, verify that the device has received the new policy.Option A — Check via CLI:
agent-charley-cli effective $TEST_DEVICE_ID
The response shows what the API will serve to the device. If your new field appears here, the API has it correctly.Option B — Check on the device (macOS):The agent stores its current policy at:
Option C — Check in the dashboard:Go to Policies, select the policy type, switch to Device override, and select your test device. You should see the values you applied.
--prune will delete all server policies not in the file. If your org has other policies, pass an empty file only in a test org, or delete the specific policy by listing all policies (agent-charley-cli pull) and removing just the test one.
Or delete it from the dashboard: Policies → Device override → select device → delete.
agent-charley-cli --env dev plan --file test-policy.yamlagent-charley-cli --env dev apply --file test-policy.yaml -y
Or set CHARLEY_ENV=dev to avoid repeating the flag.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Agent Charley","colors":{"primary":"#FF5A50","light":"#FF8C6A","dark":"#FF3030"},"logo":{"light":"https://mintcdn.com/charlemagnelabs/39arrCphjmm7Dz5Y/logo/light.svg?fit=max\u0026auto=format\u0026n=39arrCphjmm7Dz5Y\u0026q=85\u0026s=0e11c5035eb5f3f263ed9fa34158fddc","dark":"https://mintcdn.com/charlemagnelabs/39arrCphjmm7Dz5Y/logo/dark.svg?fit=max\u0026auto=format\u0026n=39arrCphjmm7Dz5Y\u0026q=85\u0026s=dd89d9bc5a51e5807bef991d67e93fab"},"favicon":"https://mintcdn.com/charlemagnelabs/39arrCphjmm7Dz5Y/favicon.svg?fit=max\u0026auto=format\u0026n=39arrCphjmm7Dz5Y\u0026q=85\u0026s=e1a7557145bd4972f70af286f1c083a0","navbar":{"links":[{"href":"https://dash.charlemagnelabs.ai","label":"Dashboard"}],"primary":{"type":"button","label":"Get Started","href":"https://dash.charlemagnelabs.ai"}},"footer":{"socials":{"github":"https://github.com/Charlemagne-Labs"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"charlemagnelabs","hasAudioNarration":false,"actualSubdomain":"charlemagnelabs","customDomains":["docs.charlemagnelabs.ai"],"gitSource":{"type":"github","owner":"charlemagne-labs","repo":"agent-charley-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6a46b2615c01ed6b564eae87","collectionId":"da685b4d-23a1-40f4-add3-252b440def40","schemaVersion":"v3"},"entitlements":{},"buildId":"6a46b2615c01ed6b564eae87:success","clientVersion":"0.0.3969","searchFilterCounts":[{"language":"default","tag":"API Reference","count":10},{"language":"default","tag":"Dashboard","count":9},{"language":"default","tag":"Policy as Code","count":8},{"language":"default","tag":"Self-Hosting","count":4},{"language":"default","tag":"Integrations","count":3},{"language":"default","tag":"Overview","count":2}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"policy-as-code/testing-guide","slug":"/policy-as-code/testing-guide","pageMetadata":{"title":"End-to-End Testing Guide","description":"Verify your CLI and Policy-as-Code setup works against a real device","sidebarTitle":"Testing Guide","href":"/policy-as-code/testing-guide"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Verify your CLI and Policy-as-Code setup works against a real device\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`This guide walks through verifying that the full policy delivery chain works: CLI → API → device agent picks up the change.`}),`\n`,_jsx(Heading,{level:`2`,id:`prerequisites`,children:`Prerequisites`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`agent-charley-cli`}),` installed (see `,_jsx(_components.a,{href:`/policy-as-code/getting-started`,children:`Getting Started`}),`)`]}),`\n`,_jsxs(_components.li,{children:[`An API key with `,_jsx(_components.code,{children:`read_write`}),` scope`]}),`\n`,_jsxs(_components.li,{children:[`At least one active enrolled device (see `,_jsx(_components.a,{href:`/dashboard/devices`,children:`Devices`}),`)`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-1-verify-authentication`,children:`Step 1: Verify Authentication`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --verbose`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` plan`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` /dev/null`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` 2>\u00261`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` head`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -5`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`You should see your base URL and key prefix in the output. If you get `,_jsx(_components.code,{children:`401`}),`, the key is wrong or expired.`]}),`\n`,_jsx(_components.p,{children:`A simpler smoke test — pull current server policies:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` pull`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --output`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` /tmp/current.yaml`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`echo`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Auth OK\"`})]}),`\n`]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-2-get-your-device-id`,children:`Step 2: Get Your Device ID`}),`\n`,_jsxs(_components.p,{children:[`From the dashboard: `,_jsx(_components.strong,{children:`Devices`}),` → find your test device → copy the UUID shown under the name.`]}),`\n`,_jsx(_components.p,{children:`Or via the API:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -s`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://dash.charlemagnelabs.ai/api/devices`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"x-api-key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$CHARLEY_API_KEY`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` python3`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -m`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` json.tool`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` grep`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` device_id`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Set it in your shell:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` TEST_DEVICE_ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`your-device-uuid`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-3-check-the-current-effective-policy`,children:`Step 3: Check the Current Effective Policy`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` effective`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $TEST_DEVICE_ID`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Note the current values — you’ll compare against these after applying.`}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-4-create-a-test-policy-file`,children:`Step 4: Create a Test Policy File`}),`\n`,_jsxs(_components.p,{children:[`Create `,_jsx(_components.code,{children:`test-policy.yaml`}),` with a change you can verify on the device. A safe, visible test is toggling `,_jsx(_components.code,{children:`suppress_frontend_ui`}),` or `,_jsx(_components.code,{children:`flow_logs_enabled`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`Test Policy`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`app_config`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` scope`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`device`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` target`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\u003cyour-device-uuid>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` locked`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` data`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` flow_logs_enabled`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` suppress_frontend_ui`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Replace `,_jsx(_components.code,{children:`\u003cyour-device-uuid>`}),` with your `,_jsx(_components.code,{children:`$TEST_DEVICE_ID`}),`.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-5-plan`,children:`Step 5: Plan`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` plan`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test-policy.yaml`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Expected output:`}),`\n`,_jsx(CodeBlock,{numberOfLines:`6`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Plan: 1 to create, 0 to update, 0 to delete, 0 unchanged.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`--- /dev/null`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`+++ Test Policy (device/\u003cuuid>/app_config)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`@@ ...`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`If you see `,_jsx(_components.code,{children:`0 unchanged`}),` with no diff, the policy already matches what’s on the server.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-6-apply`,children:`Step 6: Apply`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` apply`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test-policy.yaml`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Expected output:`}),`\n`,_jsx(CodeBlock,{numberOfLines:`3`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Plan: 1 to create, 0 to update, 0 to delete, 0 unchanged.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Done.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-7-confirm-delivery-to-device`,children:`Step 7: Confirm Delivery to Device`}),`\n`,_jsx(_components.p,{children:`The device agent polls for policy updates periodically. After applying, verify that the device has received the new policy.`}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Option A — Check via CLI:`})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` effective`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $TEST_DEVICE_ID`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The response shows what the API will serve to the device. If your new field appears here, the API has it correctly.`}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Option B — Check on the device (macOS):`})}),`\n`,_jsx(_components.p,{children:`The agent stores its current policy at:`}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`~/Library/Application Support/AgentCharley/dlp_watchdog_policy.json`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`You can read it:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`cat`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ~/Library/Application`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:`\\\\ `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`Support/AgentCharley/dlp_watchdog_policy.json`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Option C — Check in the dashboard:`})}),`\n`,_jsxs(_components.p,{children:[`Go to `,_jsx(_components.strong,{children:`Policies`}),`, select the policy type, switch to `,_jsx(_components.strong,{children:`Device override`}),`, and select your test device. You should see the values you applied.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-8-test-a-dlp-policy`,children:`Step 8: Test a DLP Policy`}),`\n`,_jsx(_components.p,{children:`To test DLP end-to-end on a device where Agent Charley is running:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Apply a DLP policy with `,_jsx(_components.code,{children:`mode: warn`}),` and `,_jsx(_components.code,{children:`builtins: [credit_card]`}),`.`]}),`\n`,_jsx(_components.li,{children:`On the test device, open any text editor or browser form.`}),`\n`,_jsxs(_components.li,{children:[`Copy a test card number (use a Luhn-valid test number, e.g. `,_jsx(_components.code,{children:`4111 1111 1111 1111`}),`) to the clipboard.`]}),`\n`,_jsx(_components.li,{children:`Paste it.`}),`\n`,_jsx(_components.li,{children:`You should see a warning toast notification from Agent Charley.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Switch `,_jsx(_components.code,{children:`mode`}),` to `,_jsx(_components.code,{children:`block`}),` and repeat — the paste should be prevented and the clipboard cleared (if `,_jsx(_components.code,{children:`clear_clipboard_on_block: true`}),`).`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`step-9-clean-up`,children:`Step 9: Clean Up`}),`\n`,_jsx(_components.p,{children:`Delete the test policy after confirming delivery:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` apply`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` /dev/null`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --prune`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--prune`}),` will delete `,_jsx(_components.strong,{children:`all`}),` server policies not in the file. If your org has other policies, pass an empty file only in a test org, or delete the specific policy by listing all policies (`,_jsx(_components.code,{children:`agent-charley-cli pull`}),`) and removing just the test one.`]})}),`\n`,_jsxs(_components.p,{children:[`Or delete it from the dashboard: `,_jsx(_components.strong,{children:`Policies → Device override → select device → delete`}),`.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`common-issues`,children:`Common Issues`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Symptom`}),_jsx(_components.th,{children:`Likely Cause`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`401 Unauthorized`})}),_jsx(_components.td,{children:`Wrong or expired API key`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`403 Forbidden`})}),_jsxs(_components.td,{children:[`Read-only key used for `,_jsx(_components.code,{children:`apply`})]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`404 Not Found`}),` on group target`]}),_jsxs(_components.td,{children:[`Group doesn’t exist yet — run `,_jsx(_components.code,{children:`apply --groups groups.yaml`}),` first`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`Policy shows in `,_jsx(_components.code,{children:`effective`}),` but device hasn’t changed`]}),_jsx(_components.td,{children:`Agent is still on its poll interval; wait ~60 seconds`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Failed to load policies`})}),_jsx(_components.td,{children:`YAML parse error — check indentation (use 2-space indent)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Plan shows no changes when you expect some`}),_jsx(_components.td,{children:`The local file already matches server state — pull to verify`})]})]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`testing-against-dev-environment`,children:`Testing Against Dev Environment`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --env`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` dev`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` plan`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test-policy.yaml`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`agent-charley-cli`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --env`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` dev`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` apply`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --file`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test-policy.yaml`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -y`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Or set `,_jsx(_components.code,{children:`CHARLEY_ENV=dev`}),` to avoid repeating the flag.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"End-to-End Testing Guide","description":"Verify your CLI and Policy-as-Code setup works against a real device","sidebarTitle":"Testing Guide","href":"/policy-as-code/testing-guide"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Prerequisites","slug":"prerequisites","depth":2,"children":[]},{"title":"Step 1: Verify Authentication","slug":"step-1-verify-authentication","depth":2,"children":[]},{"title":"Step 2: Get Your Device ID","slug":"step-2-get-your-device-id","depth":2,"children":[]},{"title":"Step 3: Check the Current Effective Policy","slug":"step-3-check-the-current-effective-policy","depth":2,"children":[]},{"title":"Step 4: Create a Test Policy File","slug":"step-4-create-a-test-policy-file","depth":2,"children":[]},{"title":"Step 5: Plan","slug":"step-5-plan","depth":2,"children":[]},{"title":"Step 6: Apply","slug":"step-6-apply","depth":2,"children":[]},{"title":"Step 7: Confirm Delivery to Device","slug":"step-7-confirm-delivery-to-device","depth":2,"children":[]},{"title":"Step 8: Test a DLP Policy","slug":"step-8-test-a-dlp-policy","depth":2,"children":[]},{"title":"Step 9: Clean Up","slug":"step-9-clean-up","depth":2,"children":[]},{"title":"Common Issues","slug":"common-issues","depth":2,"children":[]},{"title":"Testing Against Dev Environment","slug":"testing-against-dev-environment","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"charlemagnelabs","siteName":"Agent Charley","title":"End-to-End Testing Guide - Agent Charley","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-07-02T18:48:13.357Z","originalFileLocation":"policy-as-code/testing-guide.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Verify your CLI and Policy-as-Code setup works against a real device\">\u003cmeta data-mint-head name=\"application-name\" content=\"Agent Charley\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"End-to-End Testing Guide - Agent Charley\">\u003cmeta data-mint-head property=\"og:description\" content=\"Verify your CLI and Policy-as-Code setup works against a real device\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Agent Charley\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://charlemagnelabs.mintlify.app/_mintlify/api/og/v2?division=Policy+as+Code\u0026amp;title=End-to-End+Testing+Guide\u0026amp;description=Verify+your+CLI+and+Policy-as-Code+setup+works+against+a+real+device\u0026amp;theme=2c360077c0e896d0d4c566a8\u0026amp;signature=102952dc4075d0865d44ff1defa3012e447ca327325f20fecb9e60bc7a36a8ee\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"End-to-End Testing Guide - Agent Charley\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Verify your CLI and Policy-as-Code setup works against a real device\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://charlemagnelabs.mintlify.app/_mintlify/api/og/v2?division=Policy+as+Code\u0026amp;title=End-to-End+Testing+Guide\u0026amp;description=Verify+your+CLI+and+Policy-as-Code+setup+works+against+a+real+device\u0026amp;theme=2c360077c0e896d0d4c566a8\u0026amp;signature=102952dc4075d0865d44ff1defa3012e447ca327325f20fecb9e60bc7a36a8ee\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/charlemagnelabs/j6sX1Az6NogZWzq_/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Agent Charley\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#FF5A50\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/policy-as-code/testing-guide.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.charlemagnelabs.ai/#organization\",\"name\":\"Agent Charley\",\"url\":\"https://docs.charlemagnelabs.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/charlemagnelabs/39arrCphjmm7Dz5Y/logo/light.svg?fit=max\u0026auto=format\u0026n=39arrCphjmm7Dz5Y\u0026q=85\u0026s=0e11c5035eb5f3f263ed9fa34158fddc\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.charlemagnelabs.ai#website\",\"name\":\"Agent Charley\",\"url\":\"https://docs.charlemagnelabs.ai\",\"publisher\":{\"@id\":\"https://docs.charlemagnelabs.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide#webpage\",\"url\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide\",\"name\":\"End-to-End Testing Guide\",\"description\":\"Verify your CLI and Policy-as-Code setup works against a real device\",\"dateModified\":\"2026-07-02T18:48:13.357Z\",\"isPartOf\":{\"@id\":\"https://docs.charlemagnelabs.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Policy as Code\",\"item\":\"https://docs.charlemagnelabs.ai/policy-as-code/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"End-to-End Testing Guide\",\"item\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide#article\",\"headline\":\"End-to-End Testing Guide\",\"name\":\"End-to-End Testing Guide\",\"description\":\"Verify your CLI and Policy-as-Code setup works against a real device\",\"url\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide\",\"mainEntityOfPage\":{\"@id\":\"https://docs.charlemagnelabs.ai/policy-as-code/testing-guide#webpage\"},\"dateModified\":\"2026-07-02T18:48:13.357Z\",\"publisher\":{\"@id\":\"https://docs.charlemagnelabs.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.charlemagnelabs.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Agent Charley\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Agent Charley","nav":{"global":null,"groups":[{"group":"Overview","pages":[{"title":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"}]},{"group":"Dashboard","pages":[{"title":"Overview","href":"/dashboard/overview"},{"title":"Devices","href":"/dashboard/devices"},{"title":"Groups","href":"/dashboard/groups"},{"title":"Policies","href":"/dashboard/policies"},{"title":"Members","href":"/dashboard/members"},{"title":"Billing","href":"/dashboard/billing"},{"title":"Settings","href":"/dashboard/settings"},{"title":"Notifications","href":"/dashboard/notifications"},{"title":"Download Agent Charley","href":"/dashboard/download"}]},{"group":"Policy as Code","pages":[{"title":"Policy as Code Overview","sidebarTitle":"Overview","href":"/policy-as-code/overview"},{"title":"API Keys","sidebarTitle":"API Keys","href":"/policy-as-code/authentication"},{"title":"Getting Started","sidebarTitle":"Getting Started","href":"/policy-as-code/getting-started"},{"title":"Policy Reference","sidebarTitle":"Policy Reference","href":"/policy-as-code/policy-reference"},{"title":"Groups","sidebarTitle":"Groups","href":"/policy-as-code/groups"},{"title":"CLI Reference","sidebarTitle":"CLI Reference","href":"/policy-as-code/cli-reference"},{"title":"Example Policies","description":"Ready-to-use policy templates for common organizational setups","sidebarTitle":"Examples","href":"/policy-as-code/examples"},{"title":"End-to-End Testing Guide","sidebarTitle":"Testing Guide","href":"/policy-as-code/testing-guide"}]},{"group":"Integrations","pages":[{"title":"Slack","description":"Receive real-time security alerts and notifications in your Slack workspace","href":"/integrations/slack"},{"title":"SSO","href":"/integrations/sso"},{"title":"Webhooks","href":"/integrations/webhooks"}]},{"group":"API Reference","pages":[{"title":"API Overview","href":"/api-reference/overview"},{"title":"Authentication","href":"/api-reference/authentication"},{"title":"Session","href":"/api-reference/session"},{"title":"Devices","href":"/api-reference/devices"},{"title":"Analytics","href":"/api-reference/analytics"},{"title":"Members \u0026 Invites","href":"/api-reference/members"},{"title":"Billing","href":"/api-reference/billing"},{"title":"Enrollment","href":"/api-reference/enrollment"},{"title":"Notifications","href":"/api-reference/notifications"},{"title":"Alert Endpoints","href":"/api-reference/alerts"}]},{"group":"Self-Hosting","pages":[{"title":"Self-Hosting Overview","href":"/self-hosting/overview"},{"title":"Environment Variables","href":"/self-hosting/environment-variables"},{"title":"Database Setup","href":"/self-hosting/database"},{"title":"Deployment","href":"/self-hosting/deployment"}]}]},"title":"End-to-End Testing Guide - Agent Charley","buildId":"dpl_G8u2B2Ji9qJYF9umedjv293TxycS","deploymentId":"dpl_G8u2B2Ji9qJYF9umedjv293TxycS","dynamics":[],"chunks":[]}