Two pieces of the "port v4's exact UI onto v5's backend" plan: - core/contract.py: new optional ModuleSpec.category field (closed set: continuity, guidance, conditioning, sampling, post, system), validated in core/schema.py, threaded through core/registry.py's FIELDS and to_manifest(). Presentation grouping, independent of STAGE (execution order) -- a module can be stage="sampling" and category="guidance" at once. Only the 4 existing modules that actually render a settings panel (alg, sharpen, appearance, full_control) got a category assigned; the other 12 have none to categorize (no SETTINGS block) and stay uncategorised, which is valid. - v4's frontend (movie_editor/frontend/*, ~29k lines, 61 files) copied verbatim into app/legacy/. core/routes.py's "/" route now serves legacy/index.html instead of the composer entry point; a <base> tag in that file resolves its own relative script/link tags against /funpack/app/legacy/ regardless of what URL it's served at, so every file moved as a unit with zero per-file path edits. Verified live: all 61 assets load 200 OK, the real v4 onboarding screen renders pixel-for- pixel (it's the actual DOM/CSS, not a reimplementation), and several v4 API calls (/api/media, /api/projects, /api/git/status) already succeed against v5's real backend by coincidence of shared route naming -- the rest 404/405 as expected, since api.js's ~90 functions haven't been rewired to v5's actual routes yet (next piece of this plan). The old composer entry point (app/index.html, app/composer/**) stays in the tree, unreferenced, until a later cleanup pass once nothing imports it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
49 lines
1.9 KiB
Python
49 lines
1.9 KiB
Python
"""Full control: the foundation stops protecting you, and says so.
|
|
|
|
The foundation's job is that nothing it does can produce a bug on its own --
|
|
values that cannot work are refused before a run starts, and a module that fails
|
|
mid-run is dropped rather than taking the generation with it.
|
|
|
|
Both of those are in the way when the point IS to see what happens. A one-step
|
|
schedule, a width the model cannot use, a modifier that throws -- someone
|
|
exploring the edges wants the real behaviour and the real traceback, not a
|
|
careful refusal. So this turns the guards off wholesale.
|
|
|
|
It is one switch, not a switch per guard, because a half-disabled safety net is
|
|
harder to reason about than either extreme: you would never know which refusal
|
|
you were still getting. And it defaults to off, because the surprising direction
|
|
has to be the one you asked for.
|
|
|
|
Nothing here silently changes behaviour: every guard that steps aside says that
|
|
it did, and every run made with this on carries it in the status.
|
|
"""
|
|
|
|
ID = "full_control"
|
|
TITLE = "Full control"
|
|
MOUNT = "settings.general"
|
|
STAGE = "load"
|
|
CATEGORY = "system"
|
|
STATUS = "proven"
|
|
|
|
SETTINGS = {
|
|
"enabled": {
|
|
"type": "bool", "default": False,
|
|
"label": "Full control",
|
|
"hint": "Stop refusing settings that look wrong, and let failures surface. "
|
|
"Anything that breaks from here is yours to keep.",
|
|
},
|
|
}
|
|
|
|
# The one place that decides what "on" means, so no caller can get the key or
|
|
# the default subtly wrong -- and offered as a CAPABILITY rather than imported,
|
|
# so nothing else has to name this module to ask. A build without it installed
|
|
# simply has nobody answering, which reads as guarded: the safe direction.
|
|
def is_on(settings) -> bool:
|
|
return bool(((settings or {}).get(ID) or {}).get("enabled", False))
|
|
|
|
|
|
WARNING = ("full control is ON: nothing is being refused or guarded, and any "
|
|
"consequences of these settings are yours")
|
|
|
|
PROVIDES = {"guards_off": is_on}
|