Preferenze e processi
Preferenze Studio, ciclo di vita e arresto dei processi.
Technical reference synchronized with Yard’s source. File names and development commands refer to the native app repository.
Implements HD005 and HD006 from HERD_2_BACKLOG.md. Validation uses temporary homes,
owned local fixture subprocesses and fake coding tools; no model calls or ordinary installation changes.
Configuration and effective settings
yard.json → ai now contains three independent booleans:
| Key | New-install default | Meaning |
|---|---|---|
studioEnabled |
true |
Studio entry points, conversations, terminals and queue controls are available. |
studioBadgeVisible |
true |
Inject the Edit in Yard shortcut, when Studio is enabled. |
devServerAutoStart |
true |
Start a frontend on a site visit, independently of Studio. |
If a new key is absent, it inherits the old developerTools value. Thus a legacy false
keeps all three disabled. The compatibility property developerTools reads Studio availability
and, when intentionally written by older callers, sets all three preferences. Serialized output
retains the old key alongside the explicit new keys. Unrelated AI keys, MCP, runtime-context settings
and unknown future keys survive edits.
sites.json supports studioBadgeVisibility and devServerAutoStart dictionaries keyed by site
name, with "inherit", "on" or "off" values. Inherit uses the corresponding global preference.
Unknown future choice strings survive round-trips and currently inherit. Existing entries in
devServerDisabled act as off unless an explicit new override is present; editing that project's
automatic setting removes its legacy entry. Unknown top-level registry keys now survive edits too.
DevelopmentSettings resolves the effective contract once. Native project settings, nginx badge
injection, the generated PHP site map, automatic server decisions and the local read API use it.
A badge override creates a dedicated nginx configuration even for an ordinary parked site.
Studio route availability is independent of injection. Proxy records have no project folder: their
project Studio/badge/automatic preferences resolve off, the upstream remains unchanged, and the
inspector omits file-based project tools while retaining browser and HTTPS controls. Direct Studio,
main-build and project-runtime/isolation requests reject proxies and non-absolute/empty project paths
before any path can resolve to the app's working directory. The PHP first-page readiness wait uses the
automatic preference and its per-site override, including legacy opt-outs.
GET /api/development/settings?site=<site-name> returns the effective Studio/badge/automatic
booleans and the override choices; it remains available with Studio disabled. Studio context also
includes development. Native project preferences explain inheritance and the badge dependency.
Automatic development servers and direct workspace APIs remain available with Studio off.
Ownership and transition
A shared StudioAdmission gate issues generation tickets. Closing admission immediately rejects new
Studio requests in every window. Tickets from a previous generation remain invalid after re-enable.
Registration and process launch are atomic relative to closure. Handoff Git preparation is cancelable;
shutdown also waits for admitted preparations to settle. A single StudioLifecycle serializes shutdown
and queues re-enable until draining completes. It composes with existing handoff route interception.
| Process or resource | Effect of disabling Studio |
|---|---|
| Studio coding-agent run and its children | Cancel preparation, stop captured owned group, save interrupted conversation and partial answer, clear writer receipt and release execution lease. |
| Studio terminal or queue stream | Stop its captured owned group, settle SSE output, clear writer receipt, release lease. |
| Sail queue/dev command launched by Studio | Stop the tagged command in the existing container; preserve the container. |
| Development stack started only by Studio | Stop the owned stack. |
| Stack started by a normal site visit | Keep it running; global/project automatic preferences govern its separate lifecycle. |
| Stack explicitly started or adopted by project controls | Keep it running. |
| Independently supervised process or Laravel Cloud deployment | Keep it running. |
| Agents engine task, nginx, DNS, PHP-FPM, shared database/cache/mail | Keep it running; no global stop/restart operation is called. |
Changing a project's automatic preference stops an automatic-only owned stack. A manual owner or adoption protects the existing worker. Reconciliation checks ownership again when the queued stop actually runs, preventing a settings/Start race from stopping an explicitly adopted worker. The idle reaper only stops automatic stacks.
Owned macOS Process groups are captured immediately after launch and verified against the child
PID and the application's own group before negative-PID signaling. Shutdown sends TERM, waits a
bounded grace period off the main actor, escalates to KILL and waits for the child to settle. Stream
identities prevent a late completion from deleting a replacement. Active stream IDs reject duplicate
starts. Conversation completion checks its stream identity; interrupted turns cannot start a new
automatic commit. Already-running verification commands receive cancellation through NativeProcess's
owned-group cleanup. Workspace handoff ownership itself remains Studio until the user transfers it.
Evidence
DevelopmentSettingsTests exercises legacy disabled migration, independent settings across the full
boolean/override matrix, persistence/reload, unknown registry/AI fields and future override strings,
nginx Studio/badge separation including Sail, dedicated parked-site override files and PHP readiness
configuration with legacy opt-outs.
StudioLifecycleTests exercises queued re-enable, stale tickets from multiple windows, route-guard
composition, independent workspace access, duplicate concurrent stream IDs, a real owned parent and
grandchild ignoring TERM, and an unaffected independent sentinel. Additional fixtures exercise
interrupted conversation persistence/partial output/handoff lease release and automatic/manual
frontend ownership without invoking a provider model.
The initial focused run passed 5 configuration tests and 4 lifecycle tests; log
/tmp/yard-hd005-006-tests.log. The extended run passed all 15 selected tests (5 DevelopmentSettings, 6 StudioLifecycle,
3 StudioTurnVerification, 1 ProjectRuntime), including real local subprocesses and a disposable Git
handoff worktree: /tmp/yard-hd005-006-extended-tests.log. No tests were skipped in this filter.
Boundaries
These tests do not send microphone audio, execute a real provider model, stop a real Sail container, or alter the running user's services. Sail cleanup uses the existing bounded tagged-command API; container-wide shutdown remains outside Studio ownership. The lifecycle is an application/process ownership boundary, not an operating-system sandbox.
A subsequent stream review added absolute cursors for the bounded output history: reconnecting
after the 5000-chunk retention limit continues receiving new output. Its regression and all real
subprocess/ownership/conversation cases passed in /tmp/yard-hd005-018-final-tests.log. That run's
only failure was the fixture's one-yield scheduling assumption for drain entry; replacing it with
a bounded wait for the observable entry passed the targeted rerun
(/tmp/yard-hd005-018-race-test.log). Git/writer metadata checks are cancelable and run outside the
short launch admission critical section; provider output starts being collected before writer
registration completes, and completion waits for registration before clearing its lease.
Final folder-guard validation passed all 8 ProjectEnvironment tests, the ProjectRuntime lifecycle test
and the expanded direct proxy HTTP fixture (10 total) in
/tmp/yard-project-folder-final-guard-tests.log. The fixture keeps its CWD inside a temporary project,
checks that its sentinel file cannot be read or changed through proxy routes, rejects terminals and
main-build creation, preserves an independently running project's process, and leaves the fixture
environment unchanged on proxy isolation requests. The preceding settings/lifecycle/nginx filter
passed all 17 cases, including actual nginx -t, with no skips.