Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ on:
- 'plugins/**'
- 'apm.yml'
- '.github/workflows/deploy-pages.yml'
# Daily rebuild so changes to the org policy at DevExpGbb/.github/apm-policy.yml
# (which the policy page renders live at build time) get picked up even when
# this repo hasn't changed.
schedule:
- cron: '17 6 * * *'
workflow_dispatch:

permissions:
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/self-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,15 @@ jobs:
apm install
echo "::endgroup::"

- name: APM audit (CI mode — supply chain + org policy)
# Publisher exemption: this repo PUBLISHES secure-baseline, which the org
# policy (DevExpGbb/.github/apm-policy.yml v2.0.0) lists in
# `required_packages`. Pinning ourselves would be a circular dependency,
# so we audit supply-chain drift but skip org-policy enforcement here.
# Consumers still get full `apm audit --ci --policy org` via apm-audit.yml.
- name: APM audit (CI mode — supply chain only, publisher exempt from org policy)
run: |
echo "::group::apm audit --ci"
apm audit --ci -f sarif -o apm-audit.sarif
echo "::group::apm audit --ci --no-policy"
apm audit --ci --no-policy -f sarif -o apm-audit.sarif
echo "::endgroup::"

- name: APM pack (validate marketplace builds + drift check)
Expand Down
2 changes: 1 addition & 1 deletion docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default defineConfig({
label: 'Governance',
items: [
{ label: 'Consumption patterns', link: '/governance/consumption-patterns/' },
{ label: 'Policy & CI', link: '/governance/policy/' },
{ label: 'Policy in force', link: '/governance/policy/' },
],
},
],
Expand Down
146 changes: 146 additions & 0 deletions docs/src/components/PolicyAtAGlance.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
import {
policy,
ENFORCEMENT,
POLICY_BLOB_URL,
POLICY_REPO,
POLICY_FILE_PATH,
policySource,
} from '../data/policy';

const enforcementCopy: Record<string, { tone: string; line: string }> = {
block: {
tone: 'block',
line: 'Violations abort `apm install` (exit 1) AND fail `apm audit --ci`. PRs cannot merge with a red audit.',
},
warn: {
tone: 'warn',
line: 'Violations are reported in audit output but do not fail the build. Treat warnings as TODOs.',
},
off: {
tone: 'info',
line: 'Policy checks are currently disabled. Compliance is voluntary.',
},
};

const tone = enforcementCopy[ENFORCEMENT]?.tone ?? 'info';
const line = enforcementCopy[ENFORCEMENT]?.line ?? '';
---
<aside class="policy-glance" data-tone={tone}>
<header class="policy-glance__header">
<div class="policy-glance__title">
<span class="policy-glance__name">{policy.name ?? 'Org APM policy'}</span>
<span class="policy-glance__version">v{policy.version ?? '?'}</span>
</div>
<span class={`policy-glance__pill policy-glance__pill--${tone}`}>
enforcement: {ENFORCEMENT}
</span>
</header>
<p class="policy-glance__line">{line}</p>
<dl class="policy-glance__meta">
<div>
<dt>Source</dt>
<dd>
<a href={POLICY_BLOB_URL} rel="noopener">
<code>{POLICY_REPO}/{POLICY_FILE_PATH}</code> ↗
</a>
</dd>
</div>
<div>
<dt>Discovery</dt>
<dd>Auto, via GitHub <code>.github</code> default-config pattern</dd>
</div>
<div>
<dt>Audited on</dt>
<dd>Every PR (<code>apm audit --ci</code>) + on every install (<code>apm install</code>)</dd>
</div>
<div>
<dt>Build snapshot</dt>
<dd>{policySource === 'live' ? 'Fetched live at build' : 'Cached snapshot (live fetch unavailable)'}</dd>
</div>
</dl>
</aside>

<style>
.policy-glance {
border-radius: 14px;
border: 1px solid var(--sl-color-gray-5);
padding: 1.1rem 1.25rem;
margin: 1rem 0 2rem;
background: var(--sl-color-bg-nav);
}
.policy-glance[data-tone='block'] {
border-left: 4px solid #dc2626;
}
.policy-glance[data-tone='warn'] {
border-left: 4px solid #d97706;
}
.policy-glance[data-tone='info'] {
border-left: 4px solid var(--sl-color-gray-4);
}
.policy-glance__header {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 0.4rem;
}
.policy-glance__title {
display: flex;
align-items: baseline;
gap: 0.6rem;
}
.policy-glance__name {
font-size: 1.05rem;
font-weight: 600;
color: var(--sl-color-white);
}
.policy-glance__version {
font-size: 0.85rem;
color: var(--sl-color-gray-3);
font-family: var(--__sl-font-mono);
}
.policy-glance__pill {
display: inline-flex;
align-items: center;
padding: 0.2rem 0.6rem;
border-radius: 999px;
font-size: 0.78rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.policy-glance__pill--block { background: #fee2e2; color: #991b1b; }
.policy-glance__pill--warn { background: #fef3c7; color: #92400e; }
.policy-glance__pill--info { background: var(--sl-color-gray-6); color: var(--sl-color-gray-2); }
:root[data-theme='dark'] .policy-glance__pill--block { background: #450a0a; color: #fecaca; }
:root[data-theme='dark'] .policy-glance__pill--warn { background: #451a03; color: #fde68a; }
.policy-glance__line {
margin: 0 0 1rem;
color: var(--sl-color-text);
}
.policy-glance__line code {
font-size: 0.92em;
}
.policy-glance__meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 0.6rem 1.25rem;
margin: 0;
font-size: 0.88rem;
}
.policy-glance__meta div { display: contents; }
.policy-glance__meta dt {
color: var(--sl-color-gray-3);
font-weight: 600;
text-transform: uppercase;
font-size: 0.7rem;
letter-spacing: 0.04em;
margin-bottom: 0.1rem;
}
.policy-glance__meta dd {
margin: 0 0 0.5rem;
color: var(--sl-color-text);
}
</style>
42 changes: 0 additions & 42 deletions docs/src/components/PolicyBanner.astro

This file was deleted.

63 changes: 63 additions & 0 deletions docs/src/components/PolicyChip.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
import { POLICY_HEADLINE, ENFORCEMENT } from '../data/policy';

interface Props {
/** Optional override label (defaults to "Governed by APM policy"). */
label?: string;
}

const { label = 'Governed by APM policy' } = Astro.props;
const href = `${import.meta.env.BASE_URL.replace(/\/$/, '')}/governance/policy/`;
---
<a class="policy-chip" href={href} data-enforcement={ENFORCEMENT} title={POLICY_HEADLINE}>
<span class="policy-chip__dot" aria-hidden="true"></span>
<span class="policy-chip__label">{label}</span>
<span class="policy-chip__arrow" aria-hidden="true">→</span>
</a>

<style>
.policy-chip {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.35rem 0.75rem;
border-radius: 999px;
border: 1px solid var(--sl-color-gray-5);
background: var(--sl-color-gray-7, var(--sl-color-bg-nav));
color: var(--sl-color-text);
font-size: 0.82rem;
font-weight: 500;
text-decoration: none;
line-height: 1.2;
transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.policy-chip:hover {
border-color: var(--sl-color-accent);
background: var(--sl-color-gray-6);
transform: translateY(-1px);
}
.policy-chip__dot {
width: 0.55rem;
height: 0.55rem;
border-radius: 50%;
background: #16a34a; /* default: enforced & green */
box-shadow: 0 0 0 2px rgba(22, 163, 74, 0.18);
}
.policy-chip[data-enforcement='warn'] .policy-chip__dot {
background: #d97706;
box-shadow: 0 0 0 2px rgba(217, 119, 6, 0.2);
}
.policy-chip[data-enforcement='off'] .policy-chip__dot {
background: var(--sl-color-gray-4);
box-shadow: none;
}
.policy-chip__arrow {
font-size: 0.95em;
opacity: 0.6;
transition: transform 120ms ease, opacity 120ms ease;
}
.policy-chip:hover .policy-chip__arrow {
transform: translateX(2px);
opacity: 1;
}
</style>
86 changes: 86 additions & 0 deletions docs/src/components/PolicyImpactTable.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
import { POLICY_IMPACTS } from '../data/policy';

/* Tiny inline markdown — `code` and *em* — so policy.ts can stay plain text. */
function inline(s: string): string {
return s
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
.replace(/(?<!\w)_([^_]+)_(?!\w)/g, '<em>$1</em>');
}
---
<table class="policy-impact">
<thead>
<tr>
<th scope="col">Area</th>
<th scope="col">Rule</th>
<th scope="col">What this means for you</th>
</tr>
</thead>
<tbody>
{POLICY_IMPACTS.map((row) => (
<tr data-severity={row.severity}>
<th scope="row">
<span class={`sev sev--${row.severity}`} aria-label={`severity: ${row.severity}`}>{row.severity}</span>
{row.area}
</th>
<td set:html={inline(row.rule)} />
<td set:html={inline(row.impact)} />
</tr>
))}
</tbody>
</table>

<style>
.policy-impact {
width: 100%;
border-collapse: collapse;
font-size: 0.92rem;
margin: 1rem 0 2rem;
}
.policy-impact th, .policy-impact td {
text-align: left;
vertical-align: top;
padding: 0.7rem 0.85rem;
border-bottom: 1px solid var(--sl-color-gray-5);
}
.policy-impact thead th {
background: var(--sl-color-bg-nav);
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--sl-color-gray-3);
}
.policy-impact tbody th {
font-weight: 600;
color: var(--sl-color-white);
width: 22%;
}
.policy-impact tbody td:nth-of-type(1) { width: 33%; color: var(--sl-color-gray-2); }
.policy-impact tbody tr:hover { background: var(--sl-color-gray-7, var(--sl-color-bg-nav)); }
.policy-impact code {
font-size: 0.9em;
background: var(--sl-color-gray-6);
padding: 0.05em 0.35em;
border-radius: 4px;
}
.sev {
display: inline-block;
margin-right: 0.45rem;
padding: 0.05rem 0.4rem;
border-radius: 4px;
font-size: 0.62rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
vertical-align: middle;
}
.sev--block { background: #fee2e2; color: #991b1b; }
.sev--warn { background: #fef3c7; color: #92400e; }
.sev--info { background: var(--sl-color-gray-6); color: var(--sl-color-gray-2); }
:root[data-theme='dark'] .sev--block { background: #450a0a; color: #fecaca; }
:root[data-theme='dark'] .sev--warn { background: #451a03; color: #fde68a; }
</style>
2 changes: 0 additions & 2 deletions docs/src/content/docs/catalog/code-kit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ description: CODE stage — architect persona for design-intent guidance during

import { LinkCard, Card, CardGrid } from '@astrojs/starlight/components';
import InstallSnippets from '../../../components/InstallSnippets.astro';
import PolicyBanner from '../../../components/PolicyBanner.astro';
import { getPlugin, REPO_URL, TIER_LABEL } from '../../../data/plugins';

export const plugin = getPlugin('code-kit');
Expand All @@ -19,7 +18,6 @@ export const tierLabel = TIER_LABEL[plugin.tier];

{plugin.description}

<PolicyBanner />

## What's inside

Expand Down
Loading
Loading