mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-04 03:41:54 +00:00
TASK-console-attention-actions: respect live role and authority evidence
This commit is contained in:
1 parent
e217332953
commit
9c806c4b09
4 files changed
+58
-28
No files matched your search
@@ -24,12 +24,17 @@ test_integrity_note:
|
||||
given: "Approval evidence is unavailable and no queue or doctor finding is observed"
|
||||
when: "Attention items are projected"
|
||||
then: "No synthetic owner decision or operational issue is created"
|
||||
- id: SCN-console-attention-authority
|
||||
given: "Integration records may name a manager as authorizer while other runtime records lack an arbiter grant"
|
||||
when: "Attention ownership is projected from the live roster"
|
||||
then: "Roster titles supply display names, integration remains Fleet handling, and no arbiter-only authority is inferred"
|
||||
observable_outcomes:
|
||||
- "Attention groups distinguish owner decisions, Fleet work, and arbiter work"
|
||||
- "Approval action ownership follows the named approver"
|
||||
- "Repeated message queue evidence produces one item"
|
||||
- "Worktree progress and unsafe Git state have distinct descriptions"
|
||||
- "Unknown evidence stays explicit rather than gaining an invented owner"
|
||||
- "Manager-authorized integration is not mislabeled as an owner or arbiter decision"
|
||||
determinism_controls:
|
||||
- "Tests pass fixed in-memory snapshots; no clock, network, or filesystem is consulted"
|
||||
anti_cheat_rationale:
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
(function (global) {
|
||||
const shortCommit = (value) => value ? String(value).slice(0, 9) : '—';
|
||||
const ownerDomainNames = {
|
||||
'release-self-host': 'Release and Self-host',
|
||||
'work-integration': 'Work and Integration',
|
||||
'project-kernel': 'Project Kernel',
|
||||
'session-manager': 'Session Manager',
|
||||
};
|
||||
|
||||
function worktreeProblemLabel(problem) {
|
||||
if (problem === 'worktree-dirty') return 'Uncommitted changes are present';
|
||||
if (problem === 'worktree-missing') return 'The managed worktree is missing';
|
||||
@@ -19,7 +12,7 @@ function worktreeProblemLabel(problem) {
|
||||
function attentionGroups(snapshot) {
|
||||
const groups = { owner: [], fleet: [], arbiter: [] };
|
||||
const agents = new Map((snapshot.agents ?? []).map((agent) => [agent.areaId, agent]));
|
||||
const agentName = (id) => ownerDomainNames[id] ?? agents.get(id)?.title ?? id ?? 'Owner not recorded';
|
||||
const agentName = (id) => agents.get(id)?.title ?? id ?? 'Owner not recorded';
|
||||
const add = (group, item) => groups[group].push(item);
|
||||
const approvals = (snapshot.approvalRequests?.items ?? []).filter((approval) => approval.status === 'pending');
|
||||
|
||||
@@ -31,6 +24,7 @@ function attentionGroups(snapshot) {
|
||||
owner: isOwner ? 'Project owner' : agentName(approval.approver),
|
||||
detail: `${agentName(approval.requester)} is waiting on ${isOwner ? 'your decision' : agentName(approval.approver)}. ${approval.summary || 'Request consequence and options are not recorded.'}`,
|
||||
evidence: [approval.task, approval.evidence].filter(Boolean).join(' · ') || 'Request evidence not recorded',
|
||||
waitSince: approval.createdAt ?? null,
|
||||
href: `#approval-${encodeURIComponent(approval.id)}`,
|
||||
action: isOwner ? 'Review request and evidence' : 'Open approval details',
|
||||
});
|
||||
@@ -73,7 +67,7 @@ function attentionGroups(snapshot) {
|
||||
tone: !hasUnsafeProblem ? 'info' : item.problems.some((problem) => problem.startsWith('git-operation:') || problem === 'worktree-missing') ? 'urgent' : 'review',
|
||||
title: !hasUnsafeProblem ? `${identity} has work ahead of main` : `${identity} worktree needs review`,
|
||||
owner: identity,
|
||||
detail: `${labels.join('; ')}.${hasAhead ? ' Ahead commits are retained work progress, not a broken repository.' : ''} ${hasUnsafeProblem ? 'Review the exact worktree before deciding on recovery.' : 'Ask the owner to review a safe convergence plan.'}`,
|
||||
detail: `${labels.join('; ')}.${hasAhead ? ' Ahead commits are retained work progress, not a broken repository.' : ''} ${hasUnsafeProblem ? 'Review the exact worktree before deciding on recovery.' : 'Ask the owning specialist or manager to review a safe convergence plan.'}`,
|
||||
evidence: [worktree?.branch, worktree?.path ?? item.path, worktree?.ahead != null ? `${worktree.ahead} ahead / ${worktree.behind ?? 0} behind` : null].filter(Boolean).join(' · ') || 'Branch and path not recorded',
|
||||
href: `#worktree-${encodeURIComponent(item.area)}`, action: 'Inspect this worktree',
|
||||
requestOwner: item.area !== 'unknown-owner' ? item.area : null,
|
||||
@@ -88,7 +82,7 @@ function attentionGroups(snapshot) {
|
||||
: finding.code.replaceAll('_', ' ').toLowerCase().replace(/^./, (letter) => letter.toUpperCase());
|
||||
add('fleet', {
|
||||
tone: finding.severity === 'error' ? 'urgent' : 'review', title: humanTitle,
|
||||
owner: recoveryGap ? 'Release and Self-host' : finding.area ? agentName(finding.area) : 'Responsible domain not recorded',
|
||||
owner: finding.area ? agentName(finding.area) : 'Responsible domain not recorded',
|
||||
detail: recoveryGap
|
||||
? `${finding.recommendation ?? 'Configure and synchronize an off-machine canonical Git boundary.'} A single disk failure could remove the only recorded recovery copy.`
|
||||
: finding.message ?? finding.recommendation ?? 'Review this condition with the responsible domain; its consequence is not recorded.',
|
||||
@@ -105,25 +99,31 @@ function attentionGroups(snapshot) {
|
||||
});
|
||||
|
||||
const waitingIntegration = (snapshot.integration ?? []).filter((item) => !['landed', 'rejected', 'superseded'].includes(item.state));
|
||||
for (const item of waitingIntegration) add('arbiter', {
|
||||
tone: 'review', title: `Integration ${item.state}`, owner: 'Session Manager / integration authority',
|
||||
detail: 'Landing is serialized. The arbiter must check the exact candidate and required receipts before proceeding.',
|
||||
evidence: `${item.sourceArea} · ${shortCommit(item.sourceCommit)} · ${item.reason ?? 'reason not recorded'}`,
|
||||
for (const item of waitingIntegration) add('fleet', {
|
||||
tone: 'review', title: `Integration ${item.state}`, owner: item.authorizedBy ? agentName(item.authorizedBy) : 'Integration authority not recorded',
|
||||
detail: 'Review the exact candidate and required receipts under the current named landing authority. Queue state does not establish that a separate owner decision is required.',
|
||||
evidence: [item.sourceArea, shortCommit(item.sourceCommit), item.authorizedBy ? `authorized by ${agentName(item.authorizedBy)}` : null, item.reason ?? 'reason not recorded'].filter(Boolean).join(' · '),
|
||||
href: '#delivery', action: 'Inspect integration queue',
|
||||
});
|
||||
|
||||
const unknownWakes = snapshot.managerWakes?.blockingCount ?? 0;
|
||||
if (unknownWakes) add('arbiter', {
|
||||
tone: 'urgent', title: `${unknownWakes} manager launch${unknownWakes === 1 ? '' : 'es'} need inspection`,
|
||||
owner: 'Session Manager', detail: 'An unknown launch blocks another scheduled wake. Inspect recorded runtime evidence; no automatic restart is available.',
|
||||
evidence: 'A reserved launch does not prove the provider is still running.',
|
||||
href: '#manager-wakes', action: 'Inspect manager launches',
|
||||
});
|
||||
if (unknownWakes) {
|
||||
const reservations = (snapshot.managerWakes?.reservations ?? []).filter((item) => item.blocksManagerWake);
|
||||
const wakeOwners = [...new Set(reservations.map((item) => agentName(item.managerId)))];
|
||||
add('fleet', {
|
||||
tone: 'urgent', title: `${unknownWakes} scheduled manager wake${unknownWakes === 1 ? '' : 's'} need inspection`,
|
||||
owner: wakeOwners.join(', ') || 'Scheduled wake owner not recorded',
|
||||
detail: 'A recorded reservation blocks another wake. Inspect current runtime evidence before acting; this record does not prove a provider is still running or establish who may restart it.',
|
||||
evidence: reservations.map((item) => [item.scheduleId, item.reservedAt, item.outcome].filter(Boolean).join(' · ')).join('; ') || 'Reservation detail unavailable',
|
||||
href: '#manager-wakes', action: 'Inspect manager launches',
|
||||
});
|
||||
}
|
||||
|
||||
const unresolvedDelivery = (snapshot.deliveryOperations ?? []).filter((operation) => ['running', 'unknown', 'succeeded'].includes(operation.state));
|
||||
if (unresolvedDelivery.length) add('arbiter', {
|
||||
if (unresolvedDelivery.length) add('fleet', {
|
||||
tone: 'urgent', title: `${unresolvedDelivery.length} delivery operation${unresolvedDelivery.length === 1 ? '' : 's'} need review`,
|
||||
owner: 'Release and Self-host', detail: 'Inspect recorded attempts and external state before considering recovery. Do not repeat effects automatically.',
|
||||
owner: [...new Set(unresolvedDelivery.map((operation) => operation.actor ? agentName(operation.actor) : 'Operation owner not recorded'))].join(', '),
|
||||
detail: 'Inspect recorded attempts and external state before considering recovery. Do not repeat effects automatically.',
|
||||
evidence: unresolvedDelivery.map((operation) => `${operation.operation} · ${operation.state} · ${shortCommit(operation.commit)}`).join('; '),
|
||||
href: '#operation-outcomes', action: 'Inspect operation outcomes',
|
||||
});
|
||||
|
||||
+2
-2
@@ -732,7 +732,7 @@ function renderAttention(groups) {
|
||||
const definitions = [
|
||||
['owner', 'Waiting on you', 'Only requests that name the project owner as decision-maker.'],
|
||||
['fleet', 'Fleet handling', 'A named domain owns the next step; unknown ownership stays explicit.'],
|
||||
['arbiter', 'Arbiter handling', 'Serialized execution and installation decisions stay with the arbiter.'],
|
||||
['arbiter', 'Arbiter handling', 'No observed item has structured evidence assigning its next step exclusively to an arbiter.'],
|
||||
];
|
||||
const total = Object.values(groups).reduce((sum, items) => sum + items.length, 0);
|
||||
setText('#attention-count', `${total} ${total === 1 ? 'item' : 'items'}`);
|
||||
@@ -743,7 +743,7 @@ function renderAttention(groups) {
|
||||
${items.length ? items.map((item) => `<article class="attention-item tone-${escapeHtml(item.tone)}">
|
||||
<span class="attention-mark" aria-hidden="true"></span><div class="attention-copy">
|
||||
<strong>${escapeHtml(item.title)}</strong><p>${escapeHtml(item.detail)}</p>
|
||||
<small>Severity: ${escapeHtml(({ urgent: 'Urgent', review: 'Review', decision: 'Decision required', info: 'Progress' })[item.tone] ?? 'Unknown')} · Owner: ${escapeHtml(item.owner)} · ${escapeHtml(item.evidence)}</small>
|
||||
<small>Severity: ${escapeHtml(({ urgent: 'Urgent', review: 'Review', decision: 'Decision required', info: 'Progress' })[item.tone] ?? 'Unknown')} · Owner: ${escapeHtml(item.owner)}${item.waitSince ? ` · Waiting ${escapeHtml(ageLabel(item.waitSince))}` : ''} · ${escapeHtml(item.evidence)}</small>
|
||||
<a href="${escapeHtml(item.href)}">${escapeHtml(item.action)}</a>
|
||||
${item.requestOwner ? `<a href="#owner-request-form" data-attention-recipient="${escapeHtml(item.requestOwner)}">Request review from ${escapeHtml(item.owner)}</a>` : ''}
|
||||
</div></article>`).join('') : `<p class="attention-empty">${escapeHtml(description)}</p>`}
|
||||
|
||||
@@ -12,7 +12,7 @@ test('SCN-console-attention-ownership: only owner-addressed pending decisions en
|
||||
],
|
||||
approvalRequests: { items: [
|
||||
{ id: 'owner-review', status: 'pending', approver: 'owner', requester: 'provider-runtime',
|
||||
title: 'Review executor boundary', task: 'TASK-RUNTIME', evidence: 'receipt:17', summary: 'Confirm the bounded scope.' },
|
||||
title: 'Review executor boundary', task: 'TASK-RUNTIME', evidence: 'receipt:17', createdAt: '2026-10-01T06:00:00Z', summary: 'Confirm the bounded scope.' },
|
||||
{ id: 'qa-review', status: 'pending', approver: 'qa', requester: 'owner-console',
|
||||
title: 'Confirm scenario path', summary: 'Review the owned test path.' },
|
||||
] },
|
||||
@@ -21,6 +21,7 @@ test('SCN-console-attention-ownership: only owner-addressed pending decisions en
|
||||
assert.deepEqual(groups.owner.map((item) => item.title), ['Review executor boundary']);
|
||||
assert.equal(groups.owner[0].href, '#approval-owner-review');
|
||||
assert.match(groups.owner[0].detail, /bounded scope/);
|
||||
assert.equal(groups.owner[0].waitSince, '2026-10-01T06:00:00Z');
|
||||
assert.equal(groups.fleet[0].owner, 'Independent QA');
|
||||
assert.equal(groups.fleet[0].action, 'Open approval details');
|
||||
assert.doesNotMatch(JSON.stringify(groups.fleet), /Approve|Reject/);
|
||||
@@ -47,20 +48,25 @@ test('SCN-console-attention-worktrees: findings group by owning area and disting
|
||||
doctor: { findings: [
|
||||
{ severity: 'warning', code: 'WORKTREE_PROBLEM', area: 'provider-runtime', path: '/work/provider', problem: 'unique-commits:2' },
|
||||
{ severity: 'warning', code: 'WORKTREE_PROBLEM', areaId: 'provider-runtime', path: '/work/provider', problem: 'worktree-dirty' },
|
||||
{ severity: 'warning', code: 'WORKTREE_PROBLEM', area: 'project-kernel', path: '/work/kernel', problem: 'unique-commits:1' },
|
||||
{ severity: 'error', code: 'WORKTREE_PROBLEM', area: 'qa', path: '/work/qa', problem: 'git-operation:REBASE_HEAD' },
|
||||
] },
|
||||
worktrees: [
|
||||
{ area: 'provider-runtime', branch: 'runtime/fix', path: '/work/provider', ahead: 2, behind: 0 },
|
||||
{ area: 'project-kernel', branch: 'kernel/change', path: '/work/kernel', ahead: 1, behind: 0 },
|
||||
{ area: 'qa', branch: 'qa/audit', path: '/work/qa', ahead: 0, behind: 0 },
|
||||
],
|
||||
});
|
||||
|
||||
assert.equal(groups.fleet.length, 2);
|
||||
assert.equal(groups.fleet.length, 3);
|
||||
const runtime = groups.fleet.find((item) => item.owner === 'Provider Runtime');
|
||||
assert.equal(runtime.tone, 'review');
|
||||
assert.match(runtime.detail, /retained work progress, not a broken repository/);
|
||||
assert.match(runtime.detail, /Ahead commits are retained work progress, not a broken repository/);
|
||||
assert.match(runtime.evidence, /runtime\/fix · \/work\/provider/);
|
||||
assert.equal(runtime.requestOwner, 'provider-runtime');
|
||||
const kernel = groups.fleet.find((item) => item.owner === 'project-kernel');
|
||||
assert.equal(kernel.tone, 'info');
|
||||
assert.match(kernel.detail, /owning specialist or manager/);
|
||||
const qa = groups.fleet.find((item) => item.owner === 'qa');
|
||||
assert.equal(qa.tone, 'urgent');
|
||||
assert.match(qa.title, /worktree needs review/);
|
||||
@@ -76,12 +82,31 @@ test('SCN-console-attention-wait-reasons: recovery and blocked task evidence kee
|
||||
});
|
||||
|
||||
const recovery = groups.fleet.find((item) => item.title === 'Off-machine recovery copy is not verified');
|
||||
assert.equal(recovery.owner, 'Release and Self-host');
|
||||
assert.equal(recovery.owner, 'Responsible domain not recorded');
|
||||
assert.match(recovery.detail, /single disk failure could remove/);
|
||||
assert.match(recovery.evidence, /ONE-DISK · abcdef012/);
|
||||
assert.match(groups.fleet.find((item) => item.evidence === 'TASK-BLOCKED').detail, /no image was saved/);
|
||||
});
|
||||
|
||||
test('SCN-console-attention-authority: roster titles name owners and integration stays with Fleet unless arbiter authority is explicit', () => {
|
||||
const groups = project({
|
||||
agents: [{ areaId: 'coordinator-7', title: 'Delivery Coordinator' }],
|
||||
integration: [
|
||||
{ state: 'awaiting-checks', sourceArea: 'build-team', sourceCommit: '1234567890abcdef', authorizedBy: 'coordinator-7' },
|
||||
{ state: 'queued', sourceArea: 'docs-team', sourceCommit: 'abcdef0123456789' },
|
||||
],
|
||||
managerWakes: { blockingCount: 1, reservations: [{ managerId: 'coordinator-7', scheduleId: 'nightly-review',
|
||||
outcome: 'reserved', blocksManagerWake: true }] },
|
||||
});
|
||||
|
||||
assert.equal(groups.fleet.length, 3);
|
||||
assert.equal(groups.fleet[0].owner, 'Delivery Coordinator');
|
||||
assert.match(groups.fleet[0].evidence, /authorized by Delivery Coordinator/);
|
||||
assert.equal(groups.fleet[1].owner, 'Integration authority not recorded');
|
||||
assert.equal(groups.fleet[2].owner, 'Delivery Coordinator');
|
||||
assert.deepEqual(groups.arbiter, []);
|
||||
});
|
||||
|
||||
test('SCN-console-attention-empty: an unavailable signal does not manufacture owner work', () => {
|
||||
const groups = project({
|
||||
approvalRequests: { available: false, reason: 'Structured approval service unavailable.' },
|
||||
|
||||
Reference in new issue
Block a user