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
37 changes: 37 additions & 0 deletions apps/web/src/router/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,41 @@ describe('router layout fork', () => {
expect(m.meta.requiredAction).toBe('read')
expect(m.meta.requiredResource).toBe('cell')
})

it('renders /contracts nested under the shell, gate degraded to cell (Batch 6)', () => {
const m = router.resolve('/contracts')
expect(m.name).toBe('contracts')
expect(m.matched.length).toBeGreaterThanOrEqual(2)
expect(m.meta.requiresAuth).toBe(true)
expect(m.meta.requiredAction).toBe('read')
expect(m.meta.requiredResource).toBe('cell')
})

it('renders /deps nested under the shell, gate degraded to cell (Batch 6)', () => {
const m = router.resolve('/deps')
expect(m.name).toBe('deps')
expect(m.matched.length).toBeGreaterThanOrEqual(2)
expect(m.meta.requiresAuth).toBe(true)
expect(m.meta.requiredAction).toBe('read')
expect(m.meta.requiredResource).toBe('cell')
})

it('renders /coverage behind only the auth gate — a self-referential meta page (Batch 6)', () => {
const m = router.resolve('/coverage')
expect(m.name).toBe('coverage')
expect(m.matched.length).toBeGreaterThanOrEqual(2)
expect(m.meta.requiresAuth).toBe(true)
// No PDP resource exists for a dev-tool self-overview — auth gate only.
expect(m.meta.requiredAction).toBeUndefined()
expect(m.meta.requiredResource).toBeUndefined()
})

it('renders /groups nested under the shell, gate degraded to cell (Batch 6)', () => {
const m = router.resolve('/groups')
expect(m.name).toBe('groups')
expect(m.matched.length).toBeGreaterThanOrEqual(2)
expect(m.meta.requiresAuth).toBe(true)
expect(m.meta.requiredAction).toBe('read')
expect(m.meta.requiredResource).toBe('cell')
})
})
38 changes: 38 additions & 0 deletions apps/web/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,44 @@ const routes: RouteRecordRaw[] = [
component: () => import('@gocell/devboard/views/cell-detail'),
meta: { requiresAuth: true, requiredAction: 'read', requiredResource: 'cell' },
},
{
// Build · Contract registry (Batch 6). Read-only; data derived from the
// static CELL_MANIFEST (governance gates / response envelopes are a
// labelled static snapshot). The backend has no `contract` PDP resource
// yet, so the gate degrades to `cell` — same gate as the cells list.
path: 'contracts',
name: 'contracts',
component: () => import('@gocell/devboard/views/contracts'),
meta: { requiresAuth: true, requiredAction: 'read', requiredResource: 'cell' },
},
{
// Build · Dependency explorer (Batch 6). Read-only; cell dependency
// graph derived from CELL_MANIFEST.dependsOnCells. No `dep` PDP resource
// exists, so the gate degrades to `cell`.
path: 'deps',
name: 'deps',
component: () => import('@gocell/devboard/views/deps'),
meta: { requiresAuth: true, requiredAction: 'read', requiredResource: 'cell' },
},
{
// Meta · Coverage matrix (Batch 6). gocell-web's own implementation
// progress board — static, self-referential, with no backend resource
// to authorize against, so it carries only the auth gate (a PDP
// `requiredAction` would fail-closed against a non-existent resource).
path: 'coverage',
name: 'coverage',
component: () => import('@gocell/devboard/views/coverage'),
meta: { requiresAuth: true },
},
{
// Operate · Smart Groups preview (Batch 6). Read-only; static group
// rules with membership computed live from CELL_MANIFEST. Same `cell`
// gate degradation as the other devboard views.
path: 'groups',
name: 'groups',
component: () => import('@gocell/devboard/views/groups'),
meta: { requiresAuth: true, requiredAction: 'read', requiredResource: 'cell' },
},
],
},
]
Expand Down
4 changes: 4 additions & 0 deletions packages/contracts/src/http/audit/list/v1/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export interface HttpAuditListV1Response {
* Opaque cross-cell correlation identifier from the originating request context. Lets consumers stitch an audited action back to its request. Empty for entries predating its introduction.
*/
correlationId?: string;
/**
* Opaque distributed trace identifier from the originating request context. Lets consumers correlate an audited action back to its trace. Empty for entries predating its introduction.
*/
traceId?: string;
occurredAt?: string;
timestamp: string;
payload?: unknown;
Expand Down
240 changes: 240 additions & 0 deletions packages/core/src/i18n/messages/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,246 @@ const enUS = {
openFull: 'Open in audit page',
},
},
contracts: {
title: 'Contract registry',
subtitle: 'Platform-wide contract topology (serve / call) derived from CELL_MANIFEST.',
count: '{n} contracts',
search: {
label: 'Search contracts',
placeholder: 'Filter by contract or cell…',
},
kind: {
all: 'All',
http: 'HTTP',
event: 'Event',
filterLabel: 'Filter by kind',
},
table: {
contract: 'Contract',
kind: 'Kind',
servers: 'Served by',
callers: 'Called by',
},
empty: 'No matching contracts.',
snapshot: {
label: 'Static snapshot',
note: 'Governance gates and response envelopes are a static snapshot, pending the backend gocell validate --strict output.',
},
gates: {
title: 'Governance gates',
subtitle: 'Run by gocell validate --strict',
ch01: 'Contract id maps 1:1 to its filesystem path',
ch02: 'Owner cell exists and is not deprecated',
ch03: 'Consumer roles are valid for the contract kind',
ch04: 'Schema $ref resolves and conforms to JSON Schema 2020-12',
ch05: 'Breaking changes carry a waiver',
ch06: 'Typed response set is a bijection with generated Response structs',
new: 'new',
countLabel: '{passed} / {total} passing',
verdict: {
pass: 'pass',
warn: 'warn',
fail: 'fail',
},
},
detail: {
empty: 'Select a contract to see details.',
panelLabel: 'Contract details',
servers: 'Served by',
callers: 'Called by',
none: 'None',
envelope: 'Typed response envelope',
envelopeNone: 'No response envelope snapshot for this contract.',
status: 'Status',
object: 'Response struct',
kind: 'Response kind',
},
envelopeKind: {
success: 'Success response',
clientError: 'Client error',
serverError: 'Server error',
},
},
deps: {
title: 'Dependencies',
subtitle: 'Cross-cell dependencies derived from CELL_MANIFEST (goda-style read-only explorer).',
count: '{n} cells',
viewsLabel: 'Dependency view switcher',
view: {
list: 'List',
graph: 'Graph',
tree: 'Tree',
matrix: 'Matrix',
},
list: {
cell: 'Cell',
dependsOn: 'Depends on',
requiredBy: 'Required by',
none: 'None',
tableLabel: 'Cell dependency list',
},
matrix: {
caption: 'Cell dependency matrix: rows depend on columns.',
depends: 'depends on',
independent: 'no dependency',
self: 'self',
},
graph: {
label: 'Cell dependency directed graph',
empty: 'No dependencies to show.',
},
tree: {
caption: 'Dependency tree: expands downward from top-level consumers.',
leaf: 'no downstream dependency',
},
detail: {
empty: 'Select a cell to see its dependencies.',
label: 'Cell dependency detail',
close: 'Dismiss',
dependsOn: 'Depends on',
requiredBy: 'Required by',
none: 'None',
},
empty: 'No cells to show.',
},
coverage: {
eyebrow: 'META · COVERAGE',
title: 'gocell-web ↔ devboard coverage',
subtitle: 'Design routes vs shipped Vue views. Hand-maintained; truth source dev-coverage.jsx.',
kpi: {
regionLabel: 'KPI summary',
shipped: 'Routes shipped',
drafted: 'Routes drafted',
gaps: 'Gaps to close',
outOfScope: 'Out of scope',
},
legend: {
regionLabel: 'Legend',
matched: 'Matched',
partial: 'Partial',
designOnly: 'Design-only',
backendOnly: 'Backend-only',
outOfScope: 'Out of scope',
},
filter: {
groupLabel: 'Filter by status',
all: 'All',
matched: 'Matched',
partial: 'Partial',
designOnly: 'Design-only',
backendOnly: 'Backend-only',
outOfScope: 'Out of scope',
},
col: {
capability: 'Capability',
web: 'gocell-web (real)',
design: 'devboard (design)',
},
status: {
matched: 'Matched',
partial: 'Partially implemented',
designOnly: 'Design-only',
backendOnly: 'Backend-only',
outOfScope: 'Out of scope',
},
caption: 'gocell-web implementation progress against design coverage.',
none: '—',
empty: 'No capabilities match the current filter.',
section: {
auth: 'Auth & onboarding',
meta: 'Meta',
access: 'Access',
operate: 'Operate',
build: 'Build · DevTools',
observe: 'Observability',
},
cap: {
login: 'Login',
firstRun: 'First-run setup',
coverage: 'Coverage matrix',
home: 'Health overview',
identities: 'Identities',
policies: 'Policies',
decisions: 'Decisions',
audit: 'Audit log',
config: 'Configuration',
flags: 'Feature flags',
cells: 'Cells list',
cellDetail: 'Cell detail',
groups: 'Smart Groups',
contracts: 'Contract registry',
deps: 'Dependencies',
workflow: 'Workflows',
ai: 'AI Studio',
observe: 'Observability v1',
},
},
groups: {
title: 'Smart Groups',
subtitle: 'Rule-based cell groups (preview; membership computed live from CELL_MANIFEST).',
count: '{n} groups',
preview: {
label: 'Preview',
note: 'Preview feature: group rules are static; members are computed live from the rule, with no backend persistence.',
},
search: {
label: 'Search groups',
placeholder: 'Filter groups…',
},
listLabel: 'Group list',
empty: 'No matching groups.',
detail: {
empty: 'Select a group to see its rule and members.',
query: 'Rule',
and: 'AND',
members: 'Members',
memberCount: '{n} members',
noMembers: 'No cell currently satisfies this rule.',
},
member: {
cell: 'Cell',
domain: 'Domain',
tier: 'Consistency',
},
field: {
domain: 'Domain',
tier: 'Consistency',
durability: 'Durability',
dependsOnCount: 'Dependency count',
producesCount: 'Produced contracts',
consumesCount: 'Consumed contracts',
},
op: {
eq: '=',
neq: '≠',
gte: '≥',
lte: '≤',
gt: '>',
lt: '<',
},
defs: {
access: {
name: 'Access domain cells',
desc: 'All cells in the Access domain.',
},
strongConsistency: {
name: 'Strong-consistency cells',
desc: 'Cells at consistency level L3.',
},
foundation: {
name: 'Foundation cells',
desc: 'Root cells that depend on no other cell.',
},
highFanin: {
name: 'High fan-in cells',
desc: 'Cells consuming five or more contracts.',
},
durable: {
name: 'Durable cells',
desc: 'Cells whose durability mode is durable.',
},
},
},
errors: {
unknown: 'An unknown error occurred. Please try again.',
network: 'Network connection failed. Please check your connection.',
Expand Down
Loading
Loading