- {whyItMatters !== null && (
+ {storySections.length > 0 && (
+
+ )}
+
+ {storySections.length === 0 && whyItMatters !== null && (
Why it matters
diff --git a/core/ui/canvas/src/app/atrium/experienceModel.test.ts b/core/ui/canvas/src/app/atrium/experienceModel.test.ts
index fc51ac6..485089f 100644
--- a/core/ui/canvas/src/app/atrium/experienceModel.test.ts
+++ b/core/ui/canvas/src/app/atrium/experienceModel.test.ts
@@ -1,6 +1,13 @@
import { describe, expect, it } from 'vitest'
-import { payloadNumber, payloadText, productDisplayName } from './experienceModel'
+import {
+ intelligenceStoryForRecord,
+ intelligenceStorySections,
+ payloadNumber,
+ payloadText,
+ productDisplayName,
+} from './experienceModel'
+import type { IntelligenceResourceRecord } from '@/api/intelligenceResourcesApi'
describe('Atrium experience model', () => {
it('orients the shell from a domain-owned product identity', () => {
@@ -19,4 +26,65 @@ describe('Atrium experience model', () => {
expect(payloadNumber({ confidence: 0.92 }, 'confidence')).toBe(0.92)
expect(payloadNumber({ confidence: 'high' }, 'confidence')).toBeNull()
})
+
+ it('projects the canonical What / Why / How / When intelligence grammar', () => {
+ const bodyMarkdown = [
+ '# Brief',
+ '',
+ '## What Changed',
+ '',
+ '- A directive moved to reported operation\\. (inference supports: case:1; uncertainty: bounded)',
+ '',
+ '## Why It Matters',
+ '',
+ '- An operating mechanism now exists\\. (inference supports: signal:1; uncertainty: bounded)',
+ '',
+ '## How We Know',
+ '',
+ '- Two admitted records support the change\\. (cited supports: observation:1, observation:2)',
+ '',
+ '## When It Changed',
+ '',
+ '- The second report arrived 39 days later\\. (cited supports: observation:1, observation:2)',
+ ].join('\n')
+
+ expect(intelligenceStorySections({ value_json: JSON.stringify({ body_markdown: bodyMarkdown }) })).toEqual([
+ { id: 'what_changed', label: 'What changed', body: 'A directive moved to reported operation.' },
+ { id: 'why_it_matters', label: 'Why it matters', body: 'An operating mechanism now exists.' },
+ { id: 'how_we_know', label: 'How we know', body: 'Two admitted records support the change.' },
+ { id: 'when_it_changed', label: 'When it changed', body: 'The second report arrived 39 days later.' },
+ ])
+ })
+
+ it('keeps the grammar visible for decision-facing resources without inventing facts', () => {
+ const signal: IntelligenceResourceRecord = {
+ contract: 'ace.intelligence.resource-record/v1alpha1',
+ reference: {
+ contract: 'ace.intelligence.resource-reference/v1alpha1',
+ product_id: 'product:test',
+ resource_kind: 'signal',
+ resource_id: 'signal:1',
+ resource_digest: 'sha256:signal',
+ resource_contract: 'ace.intelligence.signal/v1alpha1',
+ revision: 1,
+ as_of: '2026-08-13T12:00:00Z',
+ available_at: '2026-08-13T12:05:00Z',
+ },
+ availability: 'available',
+ title: 'A new signal arrived',
+ summary: 'An official report followed an issued directive.',
+ subject_refs: [],
+ provenance: [],
+ supersedes: null,
+ payload: {},
+ degraded_reason_refs: [],
+ }
+
+ expect(intelligenceStoryForRecord(signal)).toEqual([
+ { id: 'what_changed', label: 'What changed', body: 'An official report followed an issued directive.' },
+ { id: 'why_it_matters', label: 'Why it matters', body: 'It met the configured relevance and routing criteria, so it now warrants attention.' },
+ { id: 'how_we_know', label: 'How we know', body: 'No upstream evidence link is projected for this record.' },
+ { id: 'when_it_changed', label: 'When it changed', body: 'The evidence picture is current as of 2026-08-13T12:00:00Z; a distinct event time was not supplied.' },
+ ])
+ })
})
diff --git a/core/ui/canvas/src/app/atrium/experienceModel.ts b/core/ui/canvas/src/app/atrium/experienceModel.ts
index 58c5d65..c97082f 100644
--- a/core/ui/canvas/src/app/atrium/experienceModel.ts
+++ b/core/ui/canvas/src/app/atrium/experienceModel.ts
@@ -1,4 +1,7 @@
-import type { IntelligenceResourcePage } from '@/api/intelligenceResourcesApi'
+import type {
+ IntelligenceResourcePage,
+ IntelligenceResourceRecord,
+} from '@/api/intelligenceResourcesApi'
const INITIALISMS = new Map([
['ace', 'ACE'],
@@ -47,3 +50,178 @@ export function payloadNumber(payload: unknown, key: string): number | null {
const value = (payload as Record)[key]
return typeof value === 'number' && Number.isFinite(value) ? value : null
}
+
+export type IntelligenceStorySectionId =
+ | 'what_changed'
+ | 'why_it_matters'
+ | 'how_we_know'
+ | 'when_it_changed'
+
+export interface IntelligenceStorySection {
+ readonly id: IntelligenceStorySectionId
+ readonly label: string
+ readonly body: string
+}
+
+const STORY_SECTIONS: readonly {
+ readonly id: IntelligenceStorySectionId
+ readonly label: string
+}[] = [
+ { id: 'what_changed', label: 'What changed' },
+ { id: 'why_it_matters', label: 'Why it matters' },
+ { id: 'how_we_know', label: 'How we know' },
+ { id: 'when_it_changed', label: 'When it changed' },
+]
+
+function displayPayload(payload: unknown): Record | null {
+ if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) return null
+ return payload as Record
+}
+
+function canonicalPayloadMaterial(payload: unknown): Record | null {
+ const root = displayPayload(payload)
+ if (root === null) return null
+ const encoded = payloadText(root, 'value_json')
+ if (encoded === null) return root
+ try {
+ return displayPayload(JSON.parse(encoded))
+ } catch {
+ return root
+ }
+}
+
+function unescapeCanonicalMarkdown(value: string): string {
+ return value.replace(/\\([\\`*{}[\]()#+\-.!_>])/g, '$1').trim()
+}
+
+function claimBody(value: string): string {
+ const supportMarkers = [' (cited supports:', ' (inference supports:']
+ const markerIndexes = supportMarkers
+ .map((marker) => value.indexOf(marker))
+ .filter((index) => index >= 0)
+ const end = markerIndexes.length === 0 ? value.length : Math.min(...markerIndexes)
+ return unescapeCanonicalMarkdown(value.slice(0, end))
+}
+
+/** Project the stable What / Why / How / When grammar from an opaque resource payload. */
+export function intelligenceStorySections(payload: unknown): IntelligenceStorySection[] {
+ const root = displayPayload(payload)
+ if (root === null) return []
+
+ const direct = STORY_SECTIONS.flatMap(({ id, label }) => {
+ const body = payloadText(root, id)
+ return body === null ? [] : [{ id, label, body }]
+ })
+ if (direct.length > 0) return direct
+
+ const material = canonicalPayloadMaterial(root)
+ const markdown = material === null ? null : payloadText(material, 'body_markdown')
+ if (markdown === null) return []
+
+ const byId = new Map()
+ let active: IntelligenceStorySectionId | null = null
+ for (const line of markdown.split('\n')) {
+ const heading = /^##\s+(.+?)\s*$/.exec(line)
+ if (heading !== null) {
+ const normalized = heading[1]?.trim().toLocaleLowerCase().replace(/\s+/g, '_')
+ active = STORY_SECTIONS.some(({ id }) => id === normalized)
+ ? (normalized as IntelligenceStorySectionId)
+ : null
+ continue
+ }
+ if (active === null || !line.startsWith('- ')) continue
+ const definition = STORY_SECTIONS.find(({ id }) => id === active)
+ const body = claimBody(line.slice(2))
+ if (definition !== undefined && body.length > 0) {
+ byId.set(active, { id: active, label: definition.label, body })
+ }
+ active = null
+ }
+
+ return STORY_SECTIONS.flatMap(({ id }) => {
+ const section = byId.get(id)
+ return section === undefined ? [] : [section]
+ })
+}
+
+const DECISION_FACING_KINDS = new Set([
+ 'signal',
+ 'shift',
+ 'case',
+ 'brief',
+ 'decision',
+ 'action',
+ 'outcome',
+ 'feedback',
+])
+
+const INVARIANT_MATERIALITY: Readonly> = {
+ signal: 'It met the configured relevance and routing criteria, so it now warrants attention.',
+ shift: 'The watched state no longer matches its prior baseline, so the current picture may need reassessment.',
+ case: 'ACE has bounded the question and assembled its evidence so it is ready for investigation.',
+ brief: 'It brings the material change, evidence, timing, and uncertainty into one reviewable picture.',
+ decision: 'A governed choice is now on record and can be traced to its evidence.',
+ action: 'An authorized response is now part of the accountable decision path.',
+ outcome: 'A result is now observable and can be compared with the intended decision.',
+ feedback: 'This result can inform future ranking only through the governed learning path.',
+}
+
+const EVENT_TIME_KEYS = [
+ 'detected_at',
+ 'assembled_at',
+ 'decided_at',
+ 'authorized_at',
+ 'occurred_at',
+ 'observed_at',
+ 'generated_at',
+] as const
+
+function recordedTimeStory(record: IntelligenceResourceRecord): string {
+ const material = canonicalPayloadMaterial(record.payload)
+ const eventTime = material === null
+ ? null
+ : EVENT_TIME_KEYS
+ .map((key) => payloadText(material, key))
+ .find((value) => value !== null) ?? null
+ if (eventTime !== null) return `ACE detected or assembled this at ${eventTime}.`
+ return `The evidence picture is current as of ${record.reference.as_of}; a distinct event time was not supplied.`
+}
+
+/**
+ * Give every decision-facing resource the same readable story without inventing
+ * domain facts. Explicit domain material wins; generic fallbacks disclose when
+ * materiality or event time has not yet been supplied.
+ */
+export function intelligenceStoryForRecord(
+ record: IntelligenceResourceRecord,
+): IntelligenceStorySection[] {
+ const explicit = intelligenceStorySections(record.payload)
+ if (explicit.length > 0) return explicit
+ if (!DECISION_FACING_KINDS.has(record.reference.resource_kind)) return []
+
+ const what = record.summary ?? record.title
+ const why = payloadText(record.payload, 'why_it_matters')
+ ?? INVARIANT_MATERIALITY[record.reference.resource_kind]
+ const evidenceCount = record.provenance.length
+
+ return [
+ { id: 'what_changed', label: 'What changed', body: what },
+ {
+ id: 'why_it_matters',
+ label: 'Why it matters',
+ body: why ?? 'Its decision relevance has not yet been established.',
+ },
+ {
+ id: 'how_we_know',
+ label: 'How we know',
+ body: evidenceCount === 0
+ ? 'No upstream evidence link is projected for this record.'
+ : `${evidenceCount} governed evidence link${evidenceCount === 1 ? '' : 's'} support this record.`,
+ },
+ {
+ id: 'when_it_changed',
+ label: 'When it changed',
+ body: recordedTimeStory(record),
+ },
+ ]
+}
diff --git a/core/ui/canvas/src/design/shadcn/ui/sheet.test.tsx b/core/ui/canvas/src/design/shadcn/ui/sheet.test.tsx
new file mode 100644
index 0000000..0237a11
--- /dev/null
+++ b/core/ui/canvas/src/design/shadcn/ui/sheet.test.tsx
@@ -0,0 +1,28 @@
+import { render } from '@testing-library/react'
+import { afterEach, describe, expect, test, vi } from 'vitest'
+
+import { Sheet, SheetContent, SheetDescription, SheetTitle } from './sheet'
+
+describe('Sheet', () => {
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ test('forwards the overlay ref required by the dialog portal', () => {
+ const consoleError = vi.spyOn(console, 'error').mockImplementation(() => undefined)
+
+ render(
+
+
+ Evidence detail
+ Inspect the cited resource lineage.
+
+ ,
+ )
+
+ const refWarnings = consoleError.mock.calls.filter(([message]) =>
+ String(message).includes('Function components cannot be given refs'),
+ )
+ expect(refWarnings).toEqual([])
+ })
+})
diff --git a/core/ui/canvas/src/design/shadcn/ui/sheet.tsx b/core/ui/canvas/src/design/shadcn/ui/sheet.tsx
index f60acd2..2ddfebe 100644
--- a/core/ui/canvas/src/design/shadcn/ui/sheet.tsx
+++ b/core/ui/canvas/src/design/shadcn/ui/sheet.tsx
@@ -29,21 +29,22 @@ function SheetPortal({
return
}
-function SheetOverlay({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- )
-}
+const SheetOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+
+SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
function SheetContent({
className,
diff --git a/docs/capability-maturity.md b/docs/capability-maturity.md
index dcf5c7c..40da5cf 100644
--- a/docs/capability-maturity.md
+++ b/docs/capability-maturity.md
@@ -1,6 +1,6 @@
-# ACE 0.8.0 capability maturity
+# ACE 0.8.1 capability maturity
-ACE 0.8.0 is a developer preview. This page distinguishes the public contract from implemented
+ACE 0.8.1 is a developer preview. This page distinguishes the public contract from implemented
surfaces that remain experimental.
## Preview contract
@@ -12,13 +12,13 @@ install ace-core → configure SurrealDB and an optional provider → start ACE
→ connect → map → watch → receive a cited brief → activate → inspect resources → stop cleanly
```
-The 0.8.0 public identities are:
+The 0.8.1 public identities are:
- Python distribution: `ace-core`
- Python import: `ace`
- CLI command: `ace`
- thin MCP command: `ace-mcp-client`
-- version: `0.8.0`
+- version: `0.8.1`
The thin MCP surface contains exactly eleven tools:
diff --git a/docs/evidence/README.md b/docs/evidence/README.md
index 2f98723..cd012ad 100644
--- a/docs/evidence/README.md
+++ b/docs/evidence/README.md
@@ -28,6 +28,7 @@ superseded by later work and is kept for audit trail only.
- [ace-core 0.6.0 Measured Intelligence release closeout](measured-intelligence-v0.6.0-release-closeout-v1.md) — public, passed
- [ace-core 0.7.0 Intelligence Builder Foundation release closeout](intelligence-builder-foundation-v0.7.0-release-closeout-v1.md) — public, passed
- [ace-core 0.8.0 Intelligence OS release closeout](intelligence-os-v0.8.0-release-closeout-v1.md)
+- [ace-core 0.8.1 Intelligence Builder product-experience release candidate](intelligence-os-v0.8.1-release-candidate-v1.md)
— public, passed; exact tag, trusted publication, hashes, and checkout-free install
- [ace-core 0.8.0 Intelligence OS release candidate](intelligence-os-v0.8.0-release-candidate-v1.md)
— historical pre-publication candidate; cumulative Core, Atrium, World, Market, and package gate
diff --git a/docs/evidence/intelligence-os-v0.8.1-release-candidate-v1.md b/docs/evidence/intelligence-os-v0.8.1-release-candidate-v1.md
new file mode 100644
index 0000000..407d1ec
--- /dev/null
+++ b/docs/evidence/intelligence-os-v0.8.1-release-candidate-v1.md
@@ -0,0 +1,64 @@
+# ACE 0.8.1 Intelligence Builder product-experience release candidate
+
+Status: **candidate — publication and public-index reproduction pending**
+
+## Promise
+
+ACE 0.8.1 makes the released Intelligence Operating System easier to experience without changing
+its architecture or granting new authority. A user can enter Atrium, see durable onboarding
+progress, understand which intelligence needs a decision, inspect the exact underlying resources,
+and reproduce the paired World AI Command Center demonstration.
+
+## Candidate coordinates
+
+- base release: `ace-core==0.8.0` at tag `v0.8.0`;
+- release branch: `codex/v0.8.1-product-experience-closeout`;
+- candidate distribution: `ace-core==0.8.1`;
+- paired domain candidate: `ace-domain-world-intelligence==0.11.0`;
+- schema head: v177;
+- public MCP surface: exactly eleven tools;
+- reference action adapter: unchanged distribution 0.4.0 with `ace-core>=0.8.0,<0.9`.
+
+## Included product changes
+
+1. Atrium projects an inert onboarding profile and the exact append-only Builder session history
+ through the existing authenticated Intelligence resource plane.
+2. Atrium renders proposed, working, blocked, retrying, and complete states from durable records
+ and opens the first Brief only after `first_briefing_ready`.
+3. Intelligence, Opportunities, Agents, Connections, and Strategy are first-class product
+ destinations; Work remains downstream.
+4. Opportunities are evidence-backed decision openings represented by Cases, material Shifts, and
+ early Signals. They are not sales leads, tasks, or autonomous recommendations.
+5. ACE uses its own blue-led design system. Customer identity remains a replaceable deployment
+ overlay rather than the Core or public-domain identity.
+6. A local-only immutable resource replay supports the paired World AI Command Center demo without
+ becoming a new durable store or authority path.
+7. The shared resource-detail sheet forwards its overlay ref through the Radix boundary, keeping
+ cited Brief inspection free of React runtime warnings at desktop and mobile breakpoints.
+8. Atrium turns canonical Brief sections into visual What / Why / How / When blocks and applies
+ the same truthful display grammar to every decision-facing Signal, Shift, Case, Decision,
+ Action, Outcome, and Feedback record. Missing materiality or event time stays visibly missing;
+ unknowns, limitations, receipts, and lineage remain in the governed resource detail.
+
+## Required acceptance before publication
+
+- Core lint, fast tests, naked-kernel, Canvas, security, and Docker gates pass at the exact
+ candidate head.
+- Package identity, roadmap, evidence-index, and build-backend gates pass.
+- The Core wheel builds reproducibly, passes strict Twine validation, installs outside the
+ checkout, reports version 0.8.1, and preserves the 24-kind resource plane and eleven-tool MCP
+ boundary.
+- The paired World 0.11.0 wheel installs with public Core 0.8.1 and reproduces
+ Connect → Map → Watch → Brief plus the Atrium AI Command Center resource page.
+- Browser acceptance covers desktop and mobile command-center states without horizontal overflow
+ or uncaught console errors.
+
+## Boundaries
+
+This patch does not claim collaborative multi-tenancy, hostile-code isolation, distributed
+operation, autonomous source authorization, arbitrary web access, autonomous publication,
+general real-world causal accuracy, or general beneficial impact. Domain Packs remain inert;
+source and effect access remain separately reviewed and authorized.
+
+After publication, a separate immutable closeout will bind the tagged commit, trusted workflow,
+artifact hashes, public-index reproduction, paired World release, and any observed limitations.
diff --git a/docs/faq.md b/docs/faq.md
index 6d441a3..0f2a16a 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -4,7 +4,7 @@ This FAQ answers the operational questions that tend to appear after the archite
what happens when part of a committee fails, how conflicting claims are handled, what confidence
means, and how multiple products share SurrealDB without becoming one undifferentiated memory.
-ACE 0.8.0 is a developer preview. Answers below distinguish the supported Intelligence OS contract
+ACE 0.8.1 is a developer preview. Answers below distinguish the supported Intelligence OS contract
from broader engine capabilities whose APIs and end-to-end journeys remain experimental. See
[capability maturity](capability-maturity.md) for the authoritative boundary and
[architecture](architecture.md) for the as-built system map.
@@ -369,7 +369,7 @@ end-to-end operating journeys remain experimental in 0.8.
### What is the stable public contract today?
-ACE 0.8.0 is a developer-preview contract: the self-hosted CLI, exactly eleven thin MCP tools,
+ACE 0.8.1 is a developer-preview contract: the self-hosted CLI, exactly eleven thin MCP tools,
documented provider routes, schema migrations, public Core/Intelligence/Application packages,
inert Domain Pack boundary, and authorized Intelligence resource plane. Atrium is a supported,
optional repository-delivered preview over that same plane; it is not included in the Python
diff --git a/extensions/reference/extension.py b/extensions/reference/extension.py
index 38f8796..75c3f8b 100644
--- a/extensions/reference/extension.py
+++ b/extensions/reference/extension.py
@@ -56,7 +56,7 @@ class ProductExtension:
"""The open `product` extension — copy this file to start your own."""
name = "product"
- version = "0.8.0"
+ version = "0.8.1"
def register(self, reg: "Registry") -> None:
# This must remain the first operation. A current reference extension
diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml
index cf13ea9..7331603 100644
--- a/infra/docker-compose.yml
+++ b/infra/docker-compose.yml
@@ -40,7 +40,7 @@ services:
context: ..
dockerfile: Dockerfile
args:
- ACE_VERSION: "0.8.0"
+ ACE_VERSION: "0.8.1"
depends_on:
surrealdb:
condition: service_healthy
@@ -61,9 +61,9 @@ services:
context: ..
dockerfile: Dockerfile
args:
- ACE_VERSION: "0.8.0"
+ ACE_VERSION: "0.8.1"
labels:
- org.opencontainers.image.version: "0.8.0"
+ org.opencontainers.image.version: "0.8.1"
depends_on:
surrealdb:
condition: service_healthy
@@ -98,9 +98,9 @@ services:
context: ..
dockerfile: Dockerfile
args:
- ACE_VERSION: "0.8.0"
+ ACE_VERSION: "0.8.1"
labels:
- org.opencontainers.image.version: "0.8.0"
+ org.opencontainers.image.version: "0.8.1"
depends_on:
surrealdb:
condition: service_healthy
diff --git a/pyproject.toml b/pyproject.toml
index c480d31..3ac027d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "ace-core"
-version = "0.8.0"
+version = "0.8.1"
description = "Open Intelligence Operating System with a guided Intelligence Builder"
readme = "README.md"
license = "Apache-2.0"
diff --git a/tests/test_package_identity.py b/tests/test_package_identity.py
index 0afbd7c..374250a 100644
--- a/tests/test_package_identity.py
+++ b/tests/test_package_identity.py
@@ -20,7 +20,7 @@ def test_distribution_import_cli_and_version_identities() -> None:
project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"]
assert project["name"] == "ace-core"
- assert project["version"] == ace.__version__ == ace_mcp_client.__version__ == VERSION == "0.8.0"
+ assert project["version"] == ace.__version__ == ace_mcp_client.__version__ == VERSION == "0.8.1"
assert ProductExtension.version == project["version"]
assert project["scripts"]["ace"] == "core.engine.cli.main:cli"
assert "aiohttp>=3.14.3" in project["dependencies"]
@@ -43,7 +43,7 @@ def test_package_copy_and_public_links_are_release_ready() -> None:
def test_release_workflow_defaults_to_and_guards_current_version() -> None:
workflow = (ROOT / ".github" / "workflows" / "publish.yml").read_text(encoding="utf-8")
- assert "default: v0.8.0" in workflow
+ assert "default: v0.8.1" in workflow
assert "Validate release tag matches package version" in workflow
assert 'if [ "$RELEASE_TAG" != "v$package_version" ]' in workflow
assert "ace-core-python-distributions" in workflow
@@ -58,13 +58,13 @@ def test_release_workflow_defaults_to_and_guards_current_version() -> None:
def test_docker_image_includes_public_cli_package() -> None:
dockerfile = (ROOT / "Dockerfile").read_text(encoding="utf-8")
assert "COPY ace/ ace/" in dockerfile
- assert "ARG ACE_VERSION=0.8.0" in dockerfile
+ assert "ARG ACE_VERSION=0.8.1" in dockerfile
assert 'org.opencontainers.image.version="${ACE_VERSION}"' in dockerfile
assert "uv sync --frozen --no-dev --no-editable --no-cache" in dockerfile
compose = (ROOT / "infra" / "docker-compose.yml").read_text(encoding="utf-8")
- assert compose.count('ACE_VERSION: "0.8.0"') == 3
- assert compose.count('org.opencontainers.image.version: "0.8.0"') == 2
+ assert compose.count('ACE_VERSION: "0.8.1"') == 3
+ assert compose.count('org.opencontainers.image.version: "0.8.1"') == 2
def test_lock_tracks_the_distribution_identity() -> None:
diff --git a/tests/test_public_roadmap_positioning.py b/tests/test_public_roadmap_positioning.py
index d947ed2..ddb45c0 100644
--- a/tests/test_public_roadmap_positioning.py
+++ b/tests/test_public_roadmap_positioning.py
@@ -5,13 +5,13 @@
ROADMAP = (Path(__file__).resolve().parents[1] / "ROADMAP.md").read_text(encoding="utf-8")
ROADMAP_ONE_LINE = " ".join(ROADMAP.split())
-# The current-release assertions are the coordinated 0.8 closeout gate. Historical 0.4.1 GI2,
+# The current-release assertions are the coordinated 0.8.1 patch closeout gate. Historical 0.4.1 GI2,
# 0.4.2 builder-surface, 0.4.4 GC1, 0.5.0 T1/B1, and P1/P2 identities remain exact point-in-time
# evidence. Keep these aligned with test_evidence_index_integrity.py.
def test_current_release_and_passed_milestone_are_not_conflated() -> None:
- assert "latest published release is `ace-core` 0.8.0 on PyPI and GitHub" in ROADMAP
+ assert "latest published release is `ace-core` 0.8.1 on PyPI and GitHub" in ROADMAP
assert ROADMAP.count("| 0.4.x | Governed Cognition | **Passed** |") == 1
assert "| 0.4.0 | Governed Cognition | **Delivered** |" not in ROADMAP
assert "| 0.4.0 | Governed Cognition | **Now** |" not in ROADMAP
@@ -19,7 +19,7 @@ def test_current_release_and_passed_milestone_are_not_conflated() -> None:
assert "| 0.6.0 | Measured Intelligence | **Passed** |" in ROADMAP
assert "| 0.7.0 | Intelligence Builder Foundation | **Passed** |" in ROADMAP
readme = (Path(__file__).resolve().parents[1] / "README.md").read_text(encoding="utf-8")
- assert "0.8.0 is a published developer-preview release" in " ".join(readme.split())
+ assert "0.8.1 is a published developer-preview release" in " ".join(readme.split())
assert "| 0.8.0 | Intelligence OS Realignment | **Passed** |" in ROADMAP
assert "| 0.9.0 | Collaborative Intelligence | **Now** |" in ROADMAP
assert "| 1.0.0 | Intelligence Operating System | **Later** |" in ROADMAP
diff --git a/uv.lock b/uv.lock
index 1b9280e..a3c39b0 100644
--- a/uv.lock
+++ b/uv.lock
@@ -4,7 +4,7 @@ requires-python = "==3.12.*"
[[package]]
name = "ace-core"
-version = "0.8.0"
+version = "0.8.1"
source = { editable = "." }
dependencies = [
{ name = "aiohttp" },