- Completed Companies module for bitdefender GravityZone Public API
- Implemented: getCompanyDetails, getCompanyDetailsByUser, createCompany, suspendCompany, activateCompany, deleteCompany
- Discovered updateCompany and getCompaniesList not available; companies retrieved via network inventory
- Company types: 0=Partner, 1=Customer; createCompany accepts nested licenseSubscription via JSON passthrough
- All write operations require --confirm; raw also restricts createCompany/suspendCompany/activateCompany
- selftest 49 -> 55 passing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Completed Accounts module for bitdefender skill (GravityZone Public API)
- Added 5 methods: getAccountDetails, createAccount, updateAccount, deleteAccount, configureNotificationsSettings
- Write methods require --confirm; raw also gates createAccount/updateAccount/configureNotificationsSettings
- Param shapes validated against official docs and safe validation probes
- configureNotificationsSettings is a setter with no required param; warning documented against empty payload on live tenant
- selftest 42 -> 49 passing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- assign_policy: add inheritFromAbove option; mark VERIFIED via official docs
(policyId/targetIds/forcePolicyInheritance/inheritFromAbove; not applied to
ENFORCED-policy targets).
- setPushEventSettings: documented serviceType (splunk/cef/jsonRPC), TLS 1.2+
receiver requirement, subscribeToEventTypes event-flag map; webhook receiver
pattern noted.
- api-reference.md: cite GravityZone Support Center as authoritative source.
- add references/BUILDOUT.md — master checklist to implement every API method
module-by-module; seeded with current done/todo/dead state.
- memory: reference_gravityzone_support (+ index).
selftest 42/42.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-verified the live tenant's full API scope and wrapped the modules the key
allows but the skill didn't expose. New CLI subcommands:
- assign-policy (gated) — apply an existing policy to endpoints/groups
(param shape policyId+targetIds verified live)
- reports, accounts, notif-settings, scan-tasks — read
- push-settings / push-stats / push-set (gated) — push event service
(status param verified; needs a receiver URL to enable)
Corrections from live probing:
- policies are NOT shallow: getPolicyDetails returns the FULL granular config.
Removed the false "shallow" warning; documented read+assign, console-only authoring.
- raw now gates assignPolicy + setPushEventSettings.
- documented dead modules (patchmanagement/phasr/maintenancewindows/integrations,
incidents.getIncidentsList) and unconfigured-push handled cleanly (rc0, no errorlog).
selftest 29/29 -> 42/42, all green against the live tenant.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/mailbox (ACG own-mail, single-tenant 1873b1b0) and client send (suite
Exchange Operator b43e7342, multi-tenant) stay separate on purpose: 1873b1b0
is single-tenant so it cannot serve clients; consolidating onto exchange-op was
rejected (privilege creep on casual own-mail + loses Contacts). Documented the
why in commands/mailbox.md scope boundary + feedback memory so it stops being
re-litigated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mail.Send is NOT an open decision or a 'blocked' item: the Exchange Operator
tier (b43e7342) already holds Graph Mail.Send + Mail.ReadWrite +
MailboxSettings.ReadWrite (the suite's IR victim-notification mail path).
/mailbox (ACG own-mail) separately uses the dedicated ComputerGuru Mailbox app
1873b1b0. The deleted fabb3421/Claude-MSP-Access app is now referenced only as
DELETED/do-not-use across all live surfaces.
Corrected: remediation-tool gotchas.md (removed 'suite has no mail scopes /
mailbox BLOCKED / decision-not-executed'), commands/mailbox.md (header +
Attribution no longer name the deleted app as active), feedback memory
(promoted 'suite has Mail.Send — settled' to a headline), breach-report
template, .grok mirrors, credentials.md, CATALOG_SHARED_DATA.md, and wiki
(internal-infrastructure, glaztech, dataforth). Removed dead plaintext secret
for the deleted app from CATALOG_SHARED_DATA.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/autotask exists nowhere as a Claude command (no .claude/commands/autotask.md in
the repo; only a Grok skill by that name). It was a GURU-5070-specific artifact in
the provisional manifest and produced a spurious RED on every other machine. Removing
it clears the false FAIL fleet-wide.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds .claude/scripts/migrate-to-submodules.sh — self-contained, distributable by
raw URL since old clones can't pull. Detects compliance (history merge-base vs
origin, RECLONE.md+submodule offline fallback); leaves compliant clones untouched;
otherwise re-clones AND recovers the gitignored per-machine state a clone never
carries (identity.json, settings.local.json, .mcp.json, grepai, per-project
.env/.venv/.attachments), surfaces stranded unpushed commits, and FLAGS large
purged data for manual move (never re-imports it into git). Closes RECLONE.md's
"recover any uncommitted work" gap that stranded identity.json + the discord-bot venv.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codifies the scan-first/data-driven workflow proven on Cascades (where the baked-in
non-DFS bias picked the congested channels and a data-driven DFS plan halved 5GHz retry):
- NEW survey-report.py: rolls survey-collect JSON into the fleet per-channel/per-band-group
measured busy% table + cleanest/dirtiest ranking + a suggested clean 40MHz palette. The
decision-driver that was missing (we built it by hand).
- channel-plan.sh: na palette is now DATA-DRIVEN, not hardcoded non-DFS. Adds --channels
(explicit palette) + --dfs ok|avoid|only; default considers ALL 40MHz primaries and lets
measured busy% choose. Adds load-balancing + a local-search pass -> strong co-channel to 0.
- survey-collect.sh: per-AP "cleanest" report no longer pre-filters out DFS (DFS is usually
cleanest here); marks DFS with *, points at survey-report.
- SKILL.md: documents the mandatory scan -> survey-report -> channel-plan --channels -> apply
-> validate order + the Cascades lesson.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
coord.py 'lock release' takes the lock ID; the documented path form no-ops
and strands the lock until TTL. Capture the lock ID at claim (5.0), release
it in Phase 6. Recurring friction (errorlog 2x).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per the 5070 handoff (DSCA33-45-HOFFMAN-RECOVERY): the lost DSCA33/45 specs are
recoverable from Hoffman, not John. Wired the mined dsca33-45-templates.json (56
models) into the renderer:
- datasheet-exact.js: load DSCA3345_TEMPLATES; for family DSCA, the Hoffman-mined
template takes PRECEDENCE over the stale staged-extraction entry (which shadowed 25
models with accOut "?"/no accHeader). Emit the verbatim 2-line accHeader for these
families (Vin (mVAC)/Iin (AAC)/Frequency (Hz), Output (VDC)/(mADC)). Per-model
`validated` GATE: a DSCA33/45 model renders only after byte-matching its Hoffman
original; until then it returns null (skipped) so an unverified render can never
overwrite a pristine live original. DSCA_VALIDATE_MODE env opens the gate for the
validation harness only. Exposed rendersWithoutSpecs().
- render-datasheet.js: allow a null-specs render for DSCA33/45 (their spec files were
lost; template-driven) instead of bailing on missing specs.
- derive-dsca-slotmaps.js: DSCA_TPL env to target the 3345 templates; derived 43 slot
maps into them (22 models need none, 8 DSCA33 still below threshold).
- validate-dsca3345.js (new): renders each model's _srcSerial, fetches the live
Hoffman original (GET TestReportDataFiles/{serial}, deployed uploader token — no
vault needed), content-normalized compare; --apply marks validated.
STATUS: gate is CLOSED — 0 models validated, all DSCA33/45 still render null, nothing
published, no risk. Final-Test block + accuracy headers now byte-match the Hoffman
originals for all 56 models; the remaining blocker is accuracy-DATA numeric quirks that
must match to pass the gate:
- DSCA33 calc column stored in A but displayed in mADC (x1000); measured stored in
mA (not scaled) — an original-software unit quirk.
- sign conventions differ per layout (DSCA33 stim/calc/meas unsigned, error signed;
DSCA45 stim unsigned, calc/meas/error signed).
- DSCA45 frequency-input stim formatting.
These need per-layout reverse-engineering against the originals (the validation harness
is the oracle). 8 DSCA33 models (DSCA33-02/03/03A/04/04A/05/05A/1642) also lack a slot
map (below threshold). DSCA33-1948 + DSCA45-1746 (24 units) have no Hoffman original.
Cleanups: deleted superseded memory project_dsca33_45_spec_gap; struck the obsolete
"ask John" TODO 2 from the handoff note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The DSCA33/DSCA45 main spec files lost in the cryptolocker wipe are recoverable:
the original software published correct certs to the Hoffman product API before
the wipe and our null-skipping renderer never overwrote them. Mine per-model
Final-Test templates (names + specs + verbatim accuracy headers) straight from
those originals instead of requesting spec files from Dataforth/John.
- dsca33-45-templates.json: 56 models (DSCA33 34/35, DSCA45 22/23); only
DSCA33-1948 + DSCA45-1746 (24 units) lack an original.
- mine-hoffman-dsca.py: the re-runnable miner.
- DSCA33-45-HOFFMAN-RECOVERY handoff for the AD2 session (incl. the gate:
validate each render vs its Hoffman original before enabling live rendering).
- memories: Hoffman recovery (supersedes the spec-gap "need John" note) and the
AD2 SSH MTU-blackhole root cause/fix; errorlog entries (syncro jq, ssh correction).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
While using the new 3-retry gemini path for live VPN research, two bugs surfaced:
- emit_or_fail checked auth_failed INSIDE the retry loop; a benign mid-run token-refresh line
matched the over-broad auth regex (bare login|credential|authenticat|oauth|401) and aborted the
retries with a false "auth error" - even though `gemini -p` auth tested fine. Moved auth-classify
to AFTER the retries (it only picks the final error message now) and tightened auth_failed to real
signatures (invalid_grant, not authenticated, login with google, token expired, ...).
- Added quota_exhausted() + a QUOTA FALLBACK: the pinned strong model (gemini-3.1-pro-preview) hit
"exhausted your capacity on this model" mid-session; emit_or_fail now retries once on the default
(lighter) model by stripping -m (separate quota). Validated: capped pro run -> fell back -> 2.9KB answer.
CT_THOUGHTS Thought 2 Resolution updated with both. (Search-bot reliability hardening continues.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mike's must-fix. Diagnosed from RAW output of failing queries (not guessed):
- grok xsearch = TIMEOUT: grok-4.20-multi-agent web_search runs past budget on multi-part queries
(286s/280s, rc=124, still searching - 183 thoughts, only progress-noise text); buffered json => total loss.
- gemini search = INTERMITTENT empty turn (a clean re-run gave a real 2.6KB answer in 122s); the wrapper
retried only once, so two empties in a row failed spuriously.
Fixes:
- ask-gemini.sh emit_or_fail: retry up to 3x with 3s/6s backoff (was 1).
- ask-grok.sh xsearch: --output-format streaming-json (salvage partials) + AUTO-FALLBACK to
ask-gemini.sh search when grok doesn't finish (rc!=0 or empty). Validated e2e: grok timed out
(rc=124) -> fell back -> gemini returned a real sourced answer (UniFi Teleport invite-link API).
grok's own multi-agent timeout is an xAI-side limitation; the fallback makes xsearch reliable regardless.
Docs: grok SKILL.md xsearch row + CT_THOUGHTS Thought 2 Resolution.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mike's correction: web search (grok xsearch + gemini search) carries at least as much weight as
live API probing - the searches gave the real leads this session (connector proxy, teleport setting
path); blind endpoint-probing is "highly suspect" (mostly 404s). And the search bots MUST be properly
fixed - both returned empty repeatedly on UniFi research despite the same-day partial grok fix.
- docs/CT_THOUGHTS.md: Thought 2 (HIGH PRIORITY) - web-search reliability must-fix, with the observed
failures + a proper-fix investigation plan (capture failing-query JSON; max-turns/streaming-json/
retry; cross-fallback grok<->gemini; 5/5 acceptance).
- memory feedback_web_search_over_probing: lead with web search/docs; probe only to CONFIRM a
hypothesis, never as primary discovery. Reading our own config is fine; guessing paths is not.
- errorlog correction logged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Earlier "no usable Teleport API" was wrong (probed /rest/teleport, /stat/teleport, /v1/teleport).
Gemini research + live verification: Teleport config lives at /api/s/<site>/rest/setting/teleport
(GET/PUT, also under /get/setting key 'teleport') - reachable via the connector. Brooklyn confirmed
enabled, subnet 192.168.1.1/24. Invite generate/revoke is reportedly POST /api/s/<site>/cmd/teleport
{"cmd":"generate-invite"|"revoke-invite"} (untested - it creates a live VPN access link; gate as a
write). Invites are WiFiman-app-only. Proxy path is /v1/connector/consoles/{id}/proxy/... (Gemini's
/v1/hosts/{id}/proxy form 404s). Doc updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
neighbor-collect.sh: add `--console <name> [--site <short>]` so the AP name/BSSID/IP map can come
from the cloud connector (/v1/connector/.../stat/device) instead of a UOS direct-login -- lets the
disable-analysis collector run against ANY console we have AP-VLAN reach to (the AP SSH harvest of
/proc/ui_neighbor is unchanged and still needs L3 reach). UOS path untouched. Validated against
Cascades via connector: source=CONNECTOR, built 77-mac + 450-bssid map for the 75 online APs.
This completes the hybrid (don't-lose-functionality): connector for airtime everywhere + neighbor-
collect (any source) for the SNR matrix -> NEIGHBOR_JSON -> optimize-radios disables on remote sites.
Documented (references/site-manager-api.md): the neighbor-collect --console flow, and the gateway
VPN/Teleport reach -- connector reaches /rest/networkconf (VPN servers: wireguard-server/openvpn-
server, site-to-site) read+writable in principle (gate writes like gw-control); Teleport has no
usable API (v1/ea/teleport 404, per-console /teleport 403).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validated the cloud-connector analysis against a KNOWN entity (Cascades, normally UOS-Mongo).
The connector reaches the self-hosted "UOS Server" host; Cascades is its site `va6iba3v`.
Two fixes from the validation:
- rf-analyze.py: pass macs:[<all uap macs>] to /stat/report/*.ap. The UniFi report endpoint
returns only a small DEFAULT subset otherwise -- Cascades came back as 10 of 77 APs until the
MAC list was supplied. Now profiles all 75 (uaps with 2.4 radios), matching the UOS path.
- model-rank.sh / optimize-radios.sh: --console now accepts --site <name> (internal short name
from /api/self/sites) for multi-site controllers like the UOS Server (Cascades = va6iba3v).
Result lines up with the known UOS-Mongo figures: 75 APs, 2.4GHz util 65-90% / interf 53-78% /
~1 client each, all power-down, 0 disables (roam graph absent via connector -> same coverage-safe
degradation; disables still need NEIGHBOR_JSON). Apples-to-apples confirmed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both analyses now accept `--console "<name>"` and run against the UniFi cloud connector
instead of the UOS Mongo server, so RF airtime tuning works on standalone/non-UOS consoles
(e.g. Brooklyn/Skybar). The UOS Mongo path is unchanged.
- New shared analyzer scripts/rf-analyze.py: pulls per-AP/band airtime history via the
connector POST /stat/report/hourly.ap (SAME schema as ace_stat.stat_hourly) + /stat/device
for names/zones, derives cu_interf = cu_total - cu_self_rx - cu_self_tx, and runs the SAME
model-rank ranking and optimize-radios greedy power-down/disable logic (ported faithfully).
- Roam graph (/stat/event) is usually empty on small/stationary sites -> graceful degrade:
model-rank ranks by airtime pressure; optimize-radios returns power-down candidates + 0
disables (coverage-safe). NEIGHBOR_JSON (SNR matrix) still enables disables, as on UOS.
- model-rank.sh / optimize-radios.sh: added the `--console` route (resolves the key from
vault services/unifi-site-manager, execs rf-analyze.py). Validated on Brooklyn/Skybar:
2.4GHz saturated (Yoga AP cu 63%/interf 55%), 5GHz idle (1-5%) - the expected pain-band split.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New backend reaching ANY of the ~36 ACG UniFi consoles remotely via api.ui.com with the
account key (vault services/unifi-site-manager) - no UOS server, no LAN/VPN. Mapped the API
surface empirically (key live), corroborated by grok+gemini web search:
- Tier 1 (Site Manager): fleet/devices/sites/isp commands - inventory, site health (counts,
IPS, ISP/ASN), and WAN/ISP time-series (latency/throughput/downtime).
- Tier 2 (CLOUD CONNECTOR -> console LOCAL Network API = UOS PARITY): the `net` command proxies
/v1/connector/consoles/<id>/proxy/network/api/s/<site>/stat/{device,sta}, returning the SAME
ace_stat depth as the UOS Mongo path - per-radio cu_total airtime/channel/bw/tx_power/num_sta/
satisfaction and per-client rssi/signal/noise/satisfaction/rates. Verified live on Brooklyn/
Skybar (standalone UDM, WAN-firewalled): `net brooklyn radios` + `net brooklyn clients` work.
This achieves parity with (and broader coverage than) the UOS server for non-UOS consoles.
Added references/site-manager-api.md (full catalog + 3 tiers), a Plane 3 note in SKILL.md, and
updated the reference memory. Read-only; POST actions (device restart, client block) exist, not wired.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- apply-wlan.sh: wlan_bands token was "6e" but this controller stores "6g" (verified live on Cascades
Guest SSID) -> setting 6 GHz membership would have failed. Fixed band values + option names (5g6g/6g/all).
- Cascades 2.4 runbook: folded in Phase 5 (5 GHz: width 80->40 on 76 radios; channel plan with the
DFS decision flagged -- DFS empirically clean here, so including clean-DFS gives ~20 channels vs ~5
non-DFS-only for 77 APs) and Phase 6 (6 GHz: root cause = production SSID CSCNet not on 6 GHz [bands
2g,5g only]; add 6g + enable bss-transition; band-steering already on). Per Howard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Upstream description ("You MUST use this before any creative work...") would
auto-fire the brainstorming skill on routine feature/code work. Rewrote the
frontmatter description to invoke ONLY when the user explicitly asks to
brainstorm/design. Methodology body (incl. HARD-GATE) unchanged. Noted in SOURCE.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
From the ComposioHQ/awesome-claude-skills list. Checked licenses BEFORE copying:
- threat-hunting-with-sigma-rules: repo is gone (GitHub 404) -- not harvested.
- forensics (mhattingpete): repo restructured, those skills no longer exist -- not harvested.
- pdf / mcp-builder (Anthropic official): LICENSE.txt FORBIDS copying out of the
Service / derivatives / redistribution -- NOT harvestable into this repo (install via
the official Claude Code marketplace instead if wanted).
- obra/superpowers: MIT -> the only legally harvestable set; imported with attribution.
Imported (each with its own MIT LICENSE copy + SOURCE.md provenance, commit a21956e48c13,
ASCII-normalized to house style, no emojis):
- using-git-worktrees
- test-driven-development (+ testing-anti-patterns.md)
- root-cause-tracing (+ find-polluter.sh helper, emojis -> ASCII markers)
- brainstorming (methodology only; upstream visual websocket server intentionally omitted)
Faithful imports -- content not reworded beyond ASCII typography/emoji normalization.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>