1
0

feat: senior architect quality analysis + XSS fixes + HITL guide

- Add QUALITY_ANALYSIS.md — 10-point architect review covering
  architecture coherence, completeness (~35-40% vs vision), mobile UX,
  security, test coverage, code quality, and DX
- Fix P0 XSS: mobile.html chat input now uses DOM textContent instead
  of innerHTML string interpolation with raw user input
- Fix P0 XSS: swarm_live.html agent/auction rendering rewritten with
  safe DOM methods (_t/_el helpers) — no more ${agent.name} in innerHTML
- Add M7xx test category (4 new tests) covering XSS prevention assertions;
  total suite now 232 passing (was 228)
- HITL session guide included in analysis with step-by-step phone test
  instructions and critical scenario priority ordering

https://claude.ai/code/session_0183Nzcy7TMqjrAopnTtygds
This commit is contained in:
Claude
2026-02-21 18:11:22 +00:00
parent f862ffde93
commit 95555b3738
4 changed files with 420 additions and 39 deletions

View File

@@ -104,50 +104,69 @@ function handleMessage(message) {
}
}
// Safe text setter — avoids XSS when inserting user/server data into DOM
function _t(el, text) { el.textContent = text; return el; }
function _el(tag, cls) { const e = document.createElement(tag); if (cls) e.className = cls; return e; }
function updateAgentsList(agents) {
const container = document.getElementById('agents-list');
container.innerHTML = '';
if (!agents || agents.length === 0) {
container.innerHTML = '<p style="color: var(--text-muted);">No agents registered</p>';
const p = _el('p'); p.style.color = 'var(--text-muted)';
_t(p, 'No agents registered');
container.appendChild(p);
return;
}
container.innerHTML = agents.map(agent => `
<div class="agent-card">
<div class="agent-avatar">${agent.name.charAt(0).toUpperCase()}</div>
<div class="agent-info">
<div class="agent-name">${agent.name}</div>
<div class="agent-meta">${agent.description || 'No description'}</div>
<div class="agent-meta">
<span class="badge badge-${agent.status === 'active' ? 'success' : agent.status === 'busy' ? 'warning' : 'danger'}">${agent.status}</span>
${agent.min_bid} sats min bid
| ${agent.tasks_completed} tasks
| ${agent.total_earned} sats earned
</div>
</div>
</div>
`).join('');
agents.forEach(agent => {
const card = _el('div', 'agent-card');
const avatar = _el('div', 'agent-avatar');
_t(avatar, (agent.name || '?').charAt(0).toUpperCase());
const info = _el('div', 'agent-info');
const name = _el('div', 'agent-name');
_t(name, agent.name || '');
const desc = _el('div', 'agent-meta');
_t(desc, agent.description || 'No description');
const meta = _el('div', 'agent-meta');
const badge = _el('span', `badge badge-${agent.status === 'active' ? 'success' : agent.status === 'busy' ? 'warning' : 'danger'}`);
_t(badge, agent.status || '');
const stats = _el('span');
_t(stats, ` ${agent.min_bid ?? 0} sats min bid | ${agent.tasks_completed ?? 0} tasks | ${agent.total_earned ?? 0} sats earned`);
meta.appendChild(badge);
meta.appendChild(stats);
info.appendChild(name);
info.appendChild(desc);
info.appendChild(meta);
card.appendChild(avatar);
card.appendChild(info);
container.appendChild(card);
});
}
function updateAuctionsList(auctions) {
const container = document.getElementById('auctions-list');
container.innerHTML = '';
if (!auctions || auctions.length === 0) {
container.innerHTML = '<p style="color: var(--text-muted);">No active auctions</p>';
const p = _el('p'); p.style.color = 'var(--text-muted)';
_t(p, 'No active auctions');
container.appendChild(p);
return;
}
container.innerHTML = auctions.map(auction => `
<div class="agent-card">
<div class="agent-info">
<div class="agent-name">Task ${auction.task_id.slice(0, 8)}</div>
<div class="agent-meta">
${Math.round(auction.time_remaining)}s remaining
| ${auction.bid_count} bids
</div>
</div>
</div>
`).join('');
auctions.forEach(auction => {
const card = _el('div', 'agent-card');
const info = _el('div', 'agent-info');
const name = _el('div', 'agent-name');
_t(name, 'Task ' + String(auction.task_id || '').slice(0, 8));
const meta = _el('div', 'agent-meta');
_t(meta, `${Math.round(auction.time_remaining ?? 0)}s remaining | ${auction.bid_count ?? 0} bids`);
info.appendChild(name);
info.appendChild(meta);
card.appendChild(info);
container.appendChild(card);
});
}
function addLog(message, type = 'info') {