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
85 changes: 75 additions & 10 deletions app/components/agents-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,88 @@ export function AgentsView({ roster }: { roster: RosterData | null }) {
const [query, setQuery] = useState('')
const [tier, setTier] = useState('all')
const [status, setStatus] = useState('all')
const tiers = useMemo(() => Array.from(new Set((roster?.agents ?? []).map(a => a.tier))), [roster])
const statuses = useMemo(() => Array.from(new Set((roster?.agents ?? []).map(a => a.status))), [roster])
const tiers = useMemo(() => Array.from(new Set((roster?.agents ?? []).map(agent => agent.tier))), [roster])
const statuses = useMemo(() => Array.from(new Set((roster?.agents ?? []).map(agent => agent.status))), [roster])
const agentById = useMemo(() => new Map((roster?.agents ?? []).map(agent => [agent.id, agent])), [roster])
const agents = useMemo(() => (roster?.agents ?? []).filter(agent => {
const haystack = `${agent.id} ${agentDisplayName(agent.id)} ${agent.role} ${agent.triad_roles.join(' ')}`.toLowerCase()
return (!query || haystack.includes(query.toLowerCase())) && (tier === 'all' || agent.tier === tier) && (status === 'all' || agent.status === status)
}), [roster, query, tier, status])

return <div className="view-stack">
<section className="section-heading standalone"><div><span className="eyebrow">AGENTS & FORMATIONS</span><h2>Function first. Codename second.</h2><p>Runtime roster facts remain visible without forcing external readers to decode project-local identities before understanding the role.</p></div></section>
<section className="panel filter-bar" aria-label="Agent filters">
<label><span>Search</span><input value={query} onChange={event => setQuery(event.target.value)} placeholder="Role, codename, formation…" /></label>
<label><span>Tier</span><select value={tier} onChange={event => setTier(event.target.value)}><option value="all">All tiers</option>{tiers.map(value => <option key={value}>{value}</option>)}</select></label>
<label><span>Status</span><select value={status} onChange={event => setStatus(event.target.value)}><option value="all">All statuses</option>{statuses.map(value => <option key={value}>{value}</option>)}</select></label>
<div className="filter-count"><strong>{agents.length}</strong><span>of {roster?.agent_count ?? 0} agents</span></div>
<section className="section-heading standalone">
<div>
<span className="eyebrow">AGENTS & FORMATIONS</span>
<h2>Understand the formation before the codename.</h2>
<p>DGAF presents runtime roles, formation membership, and topology before project-local identities. The roster is observability data, not evidence of authority or efficacy.</p>
</div>
</section>
{!roster ? <div className="empty-state panel"><StatusChip state="loading"/><h3>Waiting for a validated roster snapshot</h3><p>The public translation layer remains available, but runtime roster facts will not be invented.</p></div> : <div className="agent-grid">{agents.map(agent => <article className="agent-card panel" key={agent.id}><div className="agent-top"><span className="tier-mark">{agent.tier}</span><StatusChip state={normalizeRuntimeStatus(agent.status)} label={agent.status.toUpperCase()} compact/></div><h3>{agentDisplayName(agent.id)}</h3><p className="agent-role">{agent.role}</p><div className="tag-cloud">{agent.triad_roles.map(role => <span className="tag" key={role}>{role}</span>)}</div></article>)}</div>}
<section><div className="section-heading"><div><span className="eyebrow">FORMATIONS</span><h3>Runtime triads</h3></div></div><div className="formation-grid">{(roster?.triads ?? []).map(triad => <article className="formation-card panel" key={triad.id}><div className="card-header"><h4>{triad.id.replaceAll('_', ' ')}</h4><span className="tag violet">{triad.type}</span></div><p>{triad.use_case}</p><div className="member-list">{triad.agents.map(id => <span key={id}>{agentDisplayName(id)}</span>)}</div></article>)}</div></section>

{!roster ? <div className="empty-state panel"><StatusChip state="loading"/><h3>Waiting for a validated roster snapshot</h3><p>The public translation layer remains available, but runtime roster facts will not be invented.</p></div> : <>
<section className="roster-snapshot panel panel-accent" aria-labelledby="roster-snapshot-title">
<div>
<span className="eyebrow accent">VALIDATED RUNTIME SNAPSHOT</span>
<h3 id="roster-snapshot-title">Current formation inventory</h3>
<p>This surface describes the runtime roster returned by the application. It does not grant authority, establish scientific state, or widen any agent role.</p>
</div>
<div className="roster-metrics" aria-label="Roster summary">
<div><span>Agents</span><strong>{roster.agent_count}</strong></div>
<div><span>Formations</span><strong>{roster.triad_count}</strong></div>
<div><span>NDR patterns</span><strong>{roster.ndr_patterns}</strong></div>
<div><span>Version</span><strong className="mono">{roster.version}</strong></div>
</div>
<div className="roster-provenance"><span>Source</span><strong>{roster.rosterSource ?? 'Runtime roster endpoint'}</strong><span>Format</span><strong>{roster.rosterFormat ?? 'Validated response shape'}</strong></div>
</section>

<section aria-labelledby="formation-system-title">
<div className="section-heading">
<div><span className="eyebrow">FORMATION TOPOLOGY</span><h3 id="formation-system-title">Runtime coordination groups</h3><p>Each formation is shown as a bounded coordination context. Membership does not imply broader authority.</p></div>
</div>
<div className="formation-system">
{roster.triads.length ? roster.triads.map(triad => <article className="formation-row panel" key={triad.id}>
<div className="formation-summary">
<div><span className="eyebrow">{triad.type}</span><h4>{triad.id.replaceAll('_', ' ')}</h4></div>
<p>{triad.use_case}</p>
</div>
<div className="formation-rail" role="list" aria-label={`${triad.id} members`}>
{triad.agents.map((id, index) => {
const agent = agentById.get(id)
return <div className="formation-member-wrap" role="listitem" key={id}>
{index > 0 && <span className="formation-link" aria-hidden="true" />}
<div className="formation-member">
<div className="formation-member-top"><span className="tier-mark">{agent?.tier ?? 'UNMAPPED'}</span><StatusChip state={agent ? normalizeRuntimeStatus(agent.status) : 'unknown'} label={agent?.status?.toUpperCase() ?? 'UNKNOWN'} compact /></div>
<strong>{agentDisplayName(id)}</strong>
<p>{agent?.role ?? 'Runtime role unavailable in current snapshot.'}</p>
</div>
</div>
})}
</div>
</article>) : <div className="empty-state panel"><StatusChip state="unknown"/><h3>No validated formations in this snapshot</h3><p>The interface will not infer topology from agent names or roles.</p></div>}
</div>
</section>

<section aria-labelledby="roster-directory-title">
<div className="section-heading"><div><span className="eyebrow">ROSTER DIRECTORY</span><h3 id="roster-directory-title">Inspect runtime roles</h3><p>Search and filter the validated snapshot without changing the source data.</p></div></div>
<div className="panel filter-bar" aria-label="Agent filters">
<label><span>Search</span><input value={query} onChange={event => setQuery(event.target.value)} placeholder="Role, codename, formation…" /></label>
<label><span>Tier</span><select value={tier} onChange={event => setTier(event.target.value)}><option value="all">All tiers</option>{tiers.map(value => <option key={value}>{value}</option>)}</select></label>
<label><span>Status</span><select value={status} onChange={event => setStatus(event.target.value)}><option value="all">All statuses</option>{statuses.map(value => <option key={value}>{value}</option>)}</select></label>
<div className="filter-count" aria-live="polite"><strong>{agents.length}</strong><span>of {roster.agent_count} agents</span></div>
</div>
<div className="roster-directory panel" role="table" aria-label="Validated runtime agent roster">
<div className="roster-directory-head" role="row">
<span role="columnheader">Function / identity</span><span role="columnheader">Runtime role</span><span role="columnheader">Tier / status</span><span role="columnheader">Formation roles</span>
</div>
{agents.length ? agents.map(agent => <article className="roster-row" role="row" key={agent.id}>
<div role="cell"><strong>{agentDisplayName(agent.id)}</strong><code>{agent.id}</code></div>
<p role="cell">{agent.role}</p>
<div className="roster-state" role="cell"><span className="tier-mark">{agent.tier}</span><StatusChip state={normalizeRuntimeStatus(agent.status)} label={agent.status.toUpperCase()} compact /></div>
<div className="tag-cloud" role="cell">{agent.triad_roles.map(role => <span className="tag" key={role}>{role}</span>)}</div>
</article>) : <div className="roster-no-results" role="row"><div role="cell" aria-live="polite"><StatusChip state="unknown" label="NO MATCHES" compact/><span>No validated agent matches the current filters.</span></div></div>}
</div>
</section>
</>}

<div className="alert info"><strong>Ontology boundary</strong><span>{ONTOLOGY_NOTE}</span></div>
</div>
}
34 changes: 27 additions & 7 deletions app/components/evidence-view.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import { EPOCH_SUMMARIES, EVIDENCE_STATES, TRUTH_BOUNDARY } from '../lib/governance'
import { EPOCH_SUMMARIES, EVIDENCE_STATES, NEXT_TRANSITION, TRUTH_BOUNDARY } from '../lib/governance'
import { StatusChip } from './status-chip'

const REPOSITORY_URL = 'https://github.com/ndrorchestration/DGAF-Framework/blob/main/'

export function EvidenceView() {
return <div className="view-stack">
<section className="section-heading standalone"><div><span className="eyebrow">EVIDENCE & RESEARCH</span><h2>Claims carry their scope with them.</h2><p>Engineering completion, verification, authorization, empirical observation, and efficacy are separate evidence classes in this interface.</p></div></section>
<section className="claim-ceiling panel panel-accent"><div><span className="eyebrow accent">CURRENT CLAIM CEILING</span><h3>Canonical DGAF efficacy is {TRUTH_BOUNDARY.efficacy}.</h3><p>Epoch 001 cannot support the planned primary inference because the protected mapping is unrecoverable. The successor path has not been authorized for empirical collection.</p></div><StatusChip state="not_established" label="EFFICACY NOT ESTABLISHED"/></section>
<section className="section-heading standalone"><div><span className="eyebrow">EVIDENCE & RESEARCH</span><h2>Claims carry their scope with them.</h2><p>This view separates observed evidence, repository predicates, permission, and efficacy so readers can see exactly where a claim stops.</p></div></section>

<section className="claim-ceiling panel panel-accent evidence-ceiling"><div><span className="eyebrow accent">CURRENT CLAIM CEILING</span><h3>Canonical DGAF efficacy is {TRUTH_BOUNDARY.efficacy}.</h3><p>Epoch 001 cannot support the planned primary inference because the protected mapping is unrecoverable. Epoch 002 has not been authorized for empirical collection. Satisfied custody does not bridge either gap.</p></div><StatusChip state="not_established" label="EFFICACY NOT ESTABLISHED"/></section>

<section className="evidence-lineage panel" aria-labelledby="evidence-lineage-title">
<div className="evidence-lineage-heading"><div><span className="eyebrow">CURRENT EVIDENCE LINEAGE</span><h3 id="evidence-lineage-title">What is established, what is actionable, and what remains prohibited</h3></div><p>These are separate epistemic and governance objects. Movement at one layer does not silently promote the next.</p></div>
<div className="evidence-lineage-rail">
<article className="evidence-current-node" data-kind="evidence"><span className="evidence-current-index">01</span><span className="eyebrow">REPOSITORY EVIDENCE</span><h4>Custody-v2 evidence is satisfied.</h4><p>{NEXT_TRANSITION.evidence}</p><StatusChip state="pass" label="CUSTODY SATISFIED" compact/></article>
<div className="evidence-lineage-link" aria-hidden="true"><span /></div>
<article className="evidence-current-node" data-kind="predicate"><span className="evidence-current-index">02</span><span className="eyebrow">NEXT PREDICATE</span><h4>Precollection preflight is actionable.</h4><p>{NEXT_TRANSITION.blocker}</p><StatusChip state="open" label="ACTIONABLE / NOT RETAINED" compact/></article>
<div className="evidence-lineage-link" aria-hidden="true"><span /></div>
<article className="evidence-current-node" data-kind="authority"><span className="evidence-current-index">03</span><span className="eyebrow">PERMISSION</span><h4>Successor collection remains prohibited.</h4><p>Immutable freeze remains not established, and no prepared downstream validator grants collection authority.</p><StatusChip state="not_authorized" label={TRUTH_BOUNDARY.authorization} compact/></article>
<div className="evidence-lineage-link" aria-hidden="true"><span /></div>
<article className="evidence-current-node" data-kind="claim"><span className="evidence-current-index">04</span><span className="eyebrow">CANONICAL CLAIM</span><h4>Efficacy remains outside the evidence ceiling.</h4><p>Empirical N remains {TRUTH_BOUNDARY.empiricalN}; no successor efficacy claim is established.</p><StatusChip state="not_established" label={TRUTH_BOUNDARY.efficacy} compact/></article>
</div>
</section>

<section className="source-authority panel" aria-labelledby="source-authority-title">
<div className="source-authority-copy">
<div><span className="eyebrow">PRESENTATION AUTHORITY</span><h3 id="source-authority-title">Current state is rendered from named repository truth sources.</h3></div>
<p>These links expose the documents this interface uses as presentation authority. They are references to existing governance records, not new evidence and not a substitute for the underlying artifacts.</p>
<div><span className="eyebrow">PROVENANCE ANCHORS</span><h3 id="source-authority-title">Named repository sources define the presentation boundary.</h3></div>
<p>These documents are references to existing governance records. They are not new evidence and do not replace the exact artifacts or workflow evidence beneath them.</p>
</div>
<div className="source-links">{TRUTH_BOUNDARY.sources.map(source => <a className="source-link" key={source} href={`${REPOSITORY_URL}${source}`} target="_blank" rel="noreferrer">{source}</a>)}</div>
</section>
<div className="card-grid two">{EPOCH_SUMMARIES.map(epoch => <article className="epoch-card panel" key={epoch.id}><div className="card-header"><div><span className="eyebrow">{epoch.eyebrow}</span><h3>{epoch.title}</h3></div><StatusChip state={epoch.state}/></div><p>{epoch.summary}</p><ul className="fact-list">{epoch.facts.map(fact => <li key={fact}>{fact}</li>)}</ul></article>)}</div>
<section><div className="section-heading"><div><span className="eyebrow">EPISTEMIC LEGEND</span><h3>How to read DGAF evidence states</h3></div></div><div className="evidence-list">{EVIDENCE_STATES.map(item => <article className="evidence-row panel" key={item.term}><StatusChip state={item.state} label={item.term}/><p>{item.meaning}</p></article>)}</div></section>

<section aria-labelledby="epoch-comparison-title">
<div className="section-heading"><div><span className="eyebrow">RESEARCH STATE</span><h3 id="epoch-comparison-title">Track A epoch comparison</h3><p>Historical and successor evidence remain separate records with different failure and authorization boundaries.</p></div></div>
<div className="epoch-comparison">{EPOCH_SUMMARIES.map(epoch => <article className="epoch-comparison-card panel" data-epoch={epoch.id} key={epoch.id}><div className="card-header"><div><span className="eyebrow">{epoch.eyebrow}</span><h3>{epoch.title}</h3></div><StatusChip state={epoch.state}/></div><p>{epoch.summary}</p><ul className="fact-list">{epoch.facts.map(fact => <li key={fact}>{fact}</li>)}</ul></article>)}</div>
</section>

<section className="evidence-glossary-section" aria-labelledby="evidence-glossary-title"><div className="section-heading"><div><span className="eyebrow">EPISTEMIC LEGEND</span><h3 id="evidence-glossary-title">How to read DGAF evidence states</h3><p>Status terms are claim-scoped. A stronger term is never implied by a weaker one.</p></div></div><div className="evidence-glossary panel">{EVIDENCE_STATES.map(item => <article className="evidence-glossary-row" key={item.term}><StatusChip state={item.state} label={item.term}/><p>{item.meaning}</p></article>)}</div></section>
</div>
}
1 change: 1 addition & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from 'next'
import './styles/globals.css'
import './styles/refinement.css'
import './styles/systems.css'

export const metadata: Metadata = {
title: 'DGAF — Governance Command Center',
Expand Down
Loading
Loading