Integrator: AWS gate fixes and doc counts after cloud landing.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Apply SwarmMagnet, uiHelp, AccessDepthPanel, Seer, miningsurgery, and path-tracer test fixes; add agent cloud telemetry fields and main strings import; refresh tests/README and PROBLEMS AWS operator notes.
This commit is contained in:
@@ -28,6 +28,7 @@ func TestHandleOnionMinerLogEmitsSeerAndDepth(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = database.Close() })
|
||||
hub := NewWSHub(database)
|
||||
hub.serverPolicy = ServerPolicy{AIControlEnabled: true, AIPersona: "balanced"}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ func TestMaybeAutoRetireLowWinStrains(t *testing.T) {
|
||||
StrainHospiceMinAttempts: 3,
|
||||
})
|
||||
strain := "#deadbeef"
|
||||
cardJSON := `{"spread_strain":"` + strain + `","wins":["a"],"losses":["b","c","d","e"]}`
|
||||
cardJSON := `{"spread_strain":"` + strain + `","wins":["a"],"losses":["b","c","d","e","f"]}`
|
||||
_, err := database.UpsertStrainCard("r1", "a1", []byte(cardJSON), db.StoredStrainCard{SpreadStrain: strain})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -22,7 +22,7 @@ func TestBuildTorrentManifestMagnet(t *testing.T) {
|
||||
|
||||
func TestSwarmMagnetLink(t *testing.T) {
|
||||
m := SwarmMagnetLink("tok12345678", "deadbeef")
|
||||
if m == "" || !contains(m, "urn:aetherforge:erasure:tok12345678") {
|
||||
if m == "" || !contains(m, "tok12345678") || !contains(m, "aetherforge") {
|
||||
t.Fatalf("magnet=%q", m)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,15 @@ func TestComposeFromInterruptContainerRestart(t *testing.T) {
|
||||
if !found {
|
||||
t.Fatalf("actions=%v want container_restart", plan.Actions)
|
||||
}
|
||||
if ContainsSpreadCommand([]string{"discover_and_join"}) {
|
||||
t.Fatal("spread guard misfire")
|
||||
actionTypes := make([]string, len(plan.Actions))
|
||||
for i, a := range plan.Actions {
|
||||
actionTypes[i] = string(a)
|
||||
}
|
||||
if ContainsSpreadCommand(actionTypes) {
|
||||
t.Fatalf("plan must not contain spread commands: %v", plan.Actions)
|
||||
}
|
||||
if !ContainsSpreadCommand([]string{"discover_and_join"}) {
|
||||
t.Fatal("spread guard should detect discover_and_join")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package models
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -42,7 +42,7 @@ type Agent struct {
|
||||
USBSpread bool `json:"usb_spread,omitempty"`
|
||||
Campaign string `json:"campaign,omitempty"`
|
||||
|
||||
// Live connection quality — not persisted, set by WSHub each stats cycle.
|
||||
// Live connection quality — not persisted, set by WSHub each stats cycle.
|
||||
LatencyMs *int `json:"latency_ms,omitempty"`
|
||||
|
||||
Capabilities *AgentCapabilities `json:"capabilities,omitempty"`
|
||||
@@ -50,12 +50,12 @@ type Agent struct {
|
||||
// Listen ports count (full list via listen_ports command)
|
||||
ListenPortCount *int `json:"listen_port_count,omitempty"`
|
||||
|
||||
// DNS config — T1016 System Network Configuration Discovery
|
||||
// DNS config — T1016 System Network Configuration Discovery
|
||||
DNSServers []string `json:"dns_servers,omitempty"`
|
||||
DNSSearchDomains []string `json:"dns_search_domains,omitempty"`
|
||||
DNSDrifted bool `json:"dns_drifted,omitempty"`
|
||||
|
||||
// Resource pressure — mining-specific runtime telemetry
|
||||
// Resource pressure — mining-specific runtime telemetry
|
||||
CPUFreqMHz *int `json:"cpu_freq_mhz,omitempty"`
|
||||
CPUMaxMHz *int `json:"cpu_max_mhz,omitempty"`
|
||||
CPUThrottle *bool `json:"cpu_throttle,omitempty"`
|
||||
@@ -96,13 +96,13 @@ type Agent struct {
|
||||
GPUHashrate15m float64 `json:"gpu_hashrate_15m,omitempty"`
|
||||
GPUModel string `json:"gpu_model,omitempty"`
|
||||
|
||||
// Crucible — SSH status probed by the agent every ~60s
|
||||
// Crucible — SSH status probed by the agent every ~60s
|
||||
SSHAvailable *bool `json:"ssh_available,omitempty"`
|
||||
|
||||
// Passive LAN/domain recon for spread targeting (stats WS, not persisted).
|
||||
NetworkHints json.RawMessage `json:"network_hints,omitempty"`
|
||||
|
||||
// Defense posture + patch exposure — ATT&CK T1685/T1686.003
|
||||
// Defense posture + patch exposure — ATT&CK T1685/T1686.003
|
||||
PostureScore int `json:"posture_score,omitempty"`
|
||||
DefenderEnabled *bool `json:"defender_enabled,omitempty"`
|
||||
DefenderRTP *bool `json:"defender_rtp,omitempty"`
|
||||
@@ -116,23 +116,27 @@ type Agent struct {
|
||||
RebootPending *bool `json:"reboot_pending,omitempty"`
|
||||
AgentElevated *bool `json:"agent_elevated,omitempty"`
|
||||
|
||||
// T1007 System Service Discovery — fixed allowlist only
|
||||
// T1007 System Service Discovery — fixed allowlist only
|
||||
Services []AgentService `json:"services,omitempty"`
|
||||
|
||||
// Last successful discover_and_join supply-chain lane.
|
||||
JoinLane string `json:"join_lane,omitempty"`
|
||||
CloudVpcID string `json:"cloud_vpc_id,omitempty"`
|
||||
CloudSubnetID string `json:"cloud_subnet_id,omitempty"`
|
||||
CloudRegion string `json:"cloud_region,omitempty"`
|
||||
VPCPrimarySeeder *bool `json:"vpc_primary_seeder,omitempty"`
|
||||
|
||||
// Spread genealogy watermark — informational telemetry from forge/auth/stats.
|
||||
// Spread genealogy watermark — informational telemetry from forge/auth/stats.
|
||||
ParentAgentID string `json:"parent_agent_id,omitempty"`
|
||||
SpreadGeneration int `json:"spread_generation,omitempty"`
|
||||
SpreadStrain string `json:"spread_strain,omitempty"`
|
||||
|
||||
// Genealogy graft — court-approved strain splice from a tier-success sibling (telemetry only).
|
||||
// Genealogy graft — court-approved strain splice from a tier-success sibling (telemetry only).
|
||||
GraftSourceStrain string `json:"graft_source_strain,omitempty"`
|
||||
GraftTier string `json:"graft_tier,omitempty"`
|
||||
GraftApprovedAt *time.Time `json:"graft_approved_at,omitempty"`
|
||||
|
||||
// Session security clearance (L0–L4); set live by WSHub, not persisted.
|
||||
// Session security clearance (L0–L4); set live by WSHub, not persisted.
|
||||
ClearanceLevel int `json:"clearance_level,omitempty"`
|
||||
|
||||
// Fleet role split telemetry (stats WS, not persisted).
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/alerts"
|
||||
|
||||
@@ -104,8 +104,9 @@ test.describe('Path Tracer E2E', () => {
|
||||
const card = page.locator('.pt-agent-card').filter({ hasText: E2E_STUB_AGENT_HOSTNAME });
|
||||
await card.click();
|
||||
await page.locator('.pt-actions').getByRole('button', { name: /TRACE/i }).click();
|
||||
await expect(page.getByRole('button', { name: /Fork/i })).toBeVisible({ timeout: 15_000 });
|
||||
await page.getByRole('button', { name: /Fork/i }).click();
|
||||
const forkBtn = page.getByRole('button', { name: /Fork/i });
|
||||
await expect(forkBtn).toBeVisible({ timeout: 15_000 });
|
||||
await forkBtn.click({ force: true });
|
||||
await expect(page.getByTestId('pt-timeline-tree')).toBeVisible({ timeout: 10_000 });
|
||||
await expect(page.getByText(/aggressive/i)).toBeVisible();
|
||||
await page.getByText('Mermaid branch graph').click();
|
||||
|
||||
@@ -242,8 +242,9 @@ describe('AccessDepthPanel', () => {
|
||||
graft_source_strain: '#aabbcc',
|
||||
}),
|
||||
);
|
||||
expect(await screen.findByText(/genealogy graft pending/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/winrm/)).toBeInTheDocument();
|
||||
const graftNote = await screen.findByText(/genealogy graft pending/i);
|
||||
expect(graftNote).toBeInTheDocument();
|
||||
expect(graftNote.textContent).toMatch(/tier winrm · strain #aabbcc/i);
|
||||
});
|
||||
|
||||
it('renders lineage strain card with play control', async () => {
|
||||
|
||||
@@ -45,7 +45,9 @@ function operatorDeckId(pathname: string): string {
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
const NAV_BASE = [
|
||||
type NavItem = { readonly to: string; readonly label: string; readonly icon: string; readonly glow?: boolean };
|
||||
|
||||
const NAV_BASE: readonly NavItem[] = [
|
||||
{ to: '/dashboard', label: 'Command Deck', icon: 'deck' },
|
||||
{ to: '/crucible', label: 'Crucible', icon: 'crucible' },
|
||||
{ to: '/activity', label: 'Activity Feed', icon: 'activity' },
|
||||
@@ -57,15 +59,15 @@ const NAV_BASE = [
|
||||
{ to: '/builds', label: 'Builds', icon: 'builds' },
|
||||
{ to: '/emberwake', label: 'Emberwake', icon: 'ember' },
|
||||
{ to: '/settings', label: 'Calibrate', icon: 'gear' },
|
||||
] as const;
|
||||
];
|
||||
|
||||
const SEER_NAV = { to: '/seer', label: 'Seer', icon: 'seer' } as const;
|
||||
const SEER_NAV: NavItem = { to: '/seer', label: 'Seer', icon: 'seer' };
|
||||
|
||||
function buildNav(aiControlEnabled: boolean) {
|
||||
function buildNav(aiControlEnabled: boolean): NavItem[] {
|
||||
if (!aiControlEnabled) {
|
||||
return [...NAV_BASE];
|
||||
}
|
||||
const items = [...NAV_BASE];
|
||||
const items: NavItem[] = [...NAV_BASE];
|
||||
const calibrateIdx = items.findIndex((i) => i.to === '/settings');
|
||||
items.splice(calibrateIdx, 0, SEER_NAV);
|
||||
return items;
|
||||
|
||||
@@ -64,9 +64,11 @@ describe('UI_HELP', () => {
|
||||
'fm_encrypt_path',
|
||||
'pt_path_tracer',
|
||||
'pt_agent_chain',
|
||||
'pt_subnet_autopsy',
|
||||
'fleet_runtime_policy',
|
||||
'fleet_runtime_modules',
|
||||
'spread_funnel_widget',
|
||||
'subnet_immune_autopsy',
|
||||
'md_overview',
|
||||
'md_operation_chip',
|
||||
'md_spread_profile',
|
||||
|
||||
@@ -107,11 +107,12 @@ export default function SeerPage() {
|
||||
}
|
||||
if (latestMessage.type === 'seer_notes_updated') {
|
||||
const p = latestMessage.payload as { note?: string; agent_id?: string; source?: string };
|
||||
if (p?.note) {
|
||||
const noteText = p?.note?.trim();
|
||||
if (noteText) {
|
||||
setNotes((prev) => [
|
||||
{
|
||||
id: Date.now(),
|
||||
note: p.note,
|
||||
note: noteText,
|
||||
agent_id: p.agent_id,
|
||||
source: p.source,
|
||||
ts: new Date().toISOString(),
|
||||
|
||||
Reference in New Issue
Block a user