roblox-core — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited roblox-core (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Key sources: https://create.roblox.com/docs/en-us/scripting/services, https://create.roblox.com/docs/en-us/luau, https://create.roblox.com/docs/en-us/luau/tables, https://create.roblox.com/docs/en-us/luau/type-checking, https://create.roblox.com/docs/en-us/scripting/locations, https://create.roblox.com/docs/en-us/projects/data-model, https://create.roblox.com/docs/en-us/projects/client-server, https://create.roblox.com/docs/en-us/workspace/streaming, https://create.roblox.com/docs/en-us/scripting/multithreading, https://create.roblox.com/docs/en-us/scripting/attributes
local Service = game:GetService("ServiceName"). Do this once, name the variable after the service.local Module = require(ReplicatedStorage:WaitForChild("Module"))Services are the primary way you access engine functionality instead of a traditional standard library.
Use the modern task API; the legacy globals wait(), spawn(), and delay() are deprecated/soft-deprecated:
task.wait(n?): yields for about n seconds (default one frame) and returns elapsed time.task.spawn(f, ...): schedules f to run asynchronously.task.defer(f, ...): defers f until after the current event cycle.task.cancel(thread): cancels a thread returned by task.spawn/task.defer.For parallel code, task.desynchronize() and task.synchronize() move the current thread between the parallel and serial phases.
Container / hierarchy services (visible in Explorer, part of the DataModel):
Core runtime & scripting services:
Cloud / persistence / cross-server:
Monetization:
Other high-value ones: TeleportService, AnalyticsService, HttpService (outbound only + JSONEncode/Decode), PathfindingService, etc.
Discover services with game:GetService (known services) or game:FindService (optional). Avoid using game:GetChildren() for service discovery. Not every DataModel child is a service, and services can be lazily created. Acquire each service once per script/module.
Configure an instance before parenting it to avoid redundant replication and extra changed events:
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(4, 1, 2)
part.Position = Vector3.new(0, 10, 0)
part.Parent = workspaceSet Parent last; do not use the Instance.new("Part", parent) two-argument form.
Read luau-data-types-and-serialization.md before designing persisted values or debugging serialization. DataStores, JSON, and remotes have different supported types. A successful JSONEncode is a useful check, but it does not prove that a value meets every DataStore constraint.
Gradual and opt-in. Use --!strict at the top of a file (it is file-level) or a .luaurc project configuration for project-wide type checking. Add annotations (local x: number, function signatures) for large modules. Inference does a lot of the work. Catches bugs at edit time with zero runtime cost.
RunContext.Server) → server only, with access to server APIs such as DataStores.RunContext is set to Client or Server; use ModuleScripts for shared logic.RunContext.Client/Server → can run Parallel Luau when the code calls task.desynchronize() or uses ConnectParallel(). The Actor must be parented to the DataModel and the Script must have an explicit RunContext; placing a Script inside an Actor alone does not parallelize it. require() can be called from parallel contexts only when the module itself is parallel-safe; most engine APIs and many modules are not.Modern Roblox uses BaseScript.RunContext (Legacy, Server, Client, Plugin). Legacy exists only for backward compatibility and is location-dependent; prefer explicit Server or Client for new code. RunContext is set in Studio's Properties window and is read-only at runtime.
Always branch runtime authority with RunService:IsServer() and IsClient(). IsStudio() detects the environment (Studio vs. live), not runtime context, so use it only for test/development guards.
Never put datastore writes, economy, or authoritative gameplay logic anywhere a client can influence it directly.
Inside a running experience there is no direct filesystem access (security). You cannot open arbitrary files or write player-visible logs.
What you have instead:
require works like a cached module system: a ModuleScript runs once and returns the same value on subsequent requires).For complex data you often serialize tables to JSON strings for storage or transmission.
:SetAttribute/GetAttribute for lightweight per-instance data; prefer them over legacy Value objects.Random class (Random.new(seed)) for deterministic or independent random streams instead of global math.randomseed.WaitForChild/Instance.StreamingMode defensively and avoid hard references to far-away parts.table.create(n, value), table.find(t, value), table.clone(t), and table.freeze(t)/table.isfrozen(t) are the modern helpers.require executes a ModuleScript once per environment and caches the returned value.NumberSequence, ColorSequence, and PhysicalProperties are common Roblox datatypes for particles, beams, and part materials.scripts/ServiceHelper.lua: small utilities for safely acquiring services and requiring modules with timeouts.<!-- catalog:references:start -->
<!-- catalog:references:end -->
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.