diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index e0b5816ba..87f8985ee 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -183,8 +183,11 @@ jobs:
id: test-policy
run: |
set -euo pipefail
- uv run --frozen python ls/tools/localsetup.py --source-root . test-workers --json > /tmp/localsetup-test-policy.json
+ # Admit as many shard jobs as this runner has available logical CPUs,
+ # up to the configured shard count. Each job uses its own CPU budget.
+ uv run --frozen python ls/tools/localsetup.py --source-root . test-workers --workers "$(nproc)" --json > /tmp/localsetup-test-policy.json
policy="$(python -c 'import json,sys; print(json.dumps(json.load(open(sys.argv[1])),separators=(",",":")))' /tmp/localsetup-test-policy.json)"
+ printf '%s\n' "$policy"
echo "json=$policy" >> "$GITHUB_OUTPUT"
- name: Verify framework context
@@ -277,6 +280,7 @@ jobs:
- name: Run pytest
env:
CANDIDATE_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+ LOCALSETUP_TEST_WORKERS: ${{ fromJSON(needs.framework-prerequisites.outputs.test_policy).workers_per_shard }}
run: |
set -euo pipefail
test "$(git rev-parse HEAD)" = "$CANDIDATE_SHA"
@@ -286,7 +290,7 @@ jobs:
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
sudo systemctl start "user@$(id -u).service"
systemctl --user show-environment >/dev/null
- uv run --frozen --group s3-sdk pytest -n 1 ls/tests -q \
+ uv run --frozen --group s3-sdk pytest -n "$(nproc)" ls/tests -q \
--ci-shard=${{ matrix.shard }} --ci-shards=${{ fromJSON(needs.framework-prerequisites.outputs.test_policy).shard_count }} \
--maxfail=1 --durations=20
diff --git a/AGENTS.md b/AGENTS.md
index 9cc8b20e0..c241a7498 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -39,6 +39,18 @@ Do not impose an arbitrary length cap on this file. In particular, do not trim i
Keep this file aligned with the repo's actual workflow. If a rule also belongs in installed Codex context for future converted repos, mirror the portable part into `ls/templates/codex/AGENTS.md`. If the rule is only for this checkout, keep it here.
+## Repository demo and presentation assets
+
+Use the dedicated `localsetup` CDN bucket for this repository's approved public
+demo videos, previews, and similar presentation assets. Keep source masters and
+working files in the Git-ignored `.agents/state/demo-library/`. Publish only
+reviewed assets, use descriptive versioned object paths, and verify anonymous
+access and returned bytes before linking them from documentation. Keep the
+shared `default` bucket private and preserve its existing access controls.
+Use `https://cdn.cruxexperts.com` for this CDN's authenticated S3 endpoint and
+verified public links. The GS Garage endpoint is a separate local service and
+must not be used for this repository's public demo assets.
+
## Founding Principle: Eliminate Friction and Ambiguity
LocalSetup should make work simpler and clearer. Prefer updating the existing owner of a behavior, document, workflow, tool, or check. Add a new one only when a concrete requirement cannot be met by improving existing material; keep any addition small and state the gap it fills. Add gates and process steps only for a specific safety, correctness, or acceptance need. This is the framework's [founding workflow design principle](ls/docs/WORKFLOW_STANDARD.md#founding-design-principle). Follow the scoped verification policy under [Testing Guidelines](#testing-guidelines) and [Unit-Test Concurrency Policy](#unit-test-concurrency-policy).
@@ -332,8 +344,9 @@ execution environment remain applicable; changed inputs invalidate that proof.
Run cheap audit, catalog, version, and documentation checks before expensive
validation. Hosted Python validation partitions all collected cases across the
-configured shards, with one worker per active shard. The resolved aggregate
-budget limits concurrent shards; remaining shards queue. Each shard stops
+configured shards. Each isolated runner uses its available logical CPUs for its
+shard's guarded worker pool; the resolved `max_parallel` limit controls how many
+shard jobs run at once. Remaining shards queue. Each shard stops
on its first failure, reports slow cases, and has a 60-minute job deadline. A
failed or empty shard cannot satisfy the aggregate check. Rerun failed jobs after
an understood transient failure; do not restart successful jobs without a reason.
@@ -385,7 +398,7 @@ On resume, recalculate the budget from currently available CPUs. Inspect inherit
worker overrides and do not carry forward a stale lower setting when the user
requests the full formula-based budget.
-The default aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of available logical CPUs and a tighter physical-memory capacity. Resolve and enforce the budget in code from selected configuration; agents and users edit settings, not scheduling calculations. Hosted partitions queue within that budget; local queues follow the active worker count. Concurrent test processes share the budget; they must not each claim it. Preserve stricter native execution limits.
+The default aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of available logical CPUs and a tighter physical-memory capacity. Resolve and enforce the budget in code from selected configuration; agents and users edit settings, not scheduling calculations. Hosted jobs have isolated runner budgets: each shard's worker pool is capped by that runner's available CPUs and memory, while the matrix concurrency limit bounds active jobs. Local queues follow the active worker count. Concurrent test processes on the same host share its budget; they must not each claim it. Preserve stricter native execution limits.
Test effort must be proportional to risk. For tiny docs, policy, metadata, or one-line behavior changes, prefer static checks such as `git diff --check`, targeted syntax checks, or no test run when there is no executable surface. Do not add broad or repetitive tests merely to increase evidence. Add tests only for behavior that can realistically regress, and keep test code smaller than the implementation unless the behavior is safety-critical or has multiple important edge cases. Run the smallest relevant validation first; broaden only after focused checks pass or when the affected surface justifies it.
diff --git a/README.md b/README.md
index 61104a3dd..69a9e186d 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,16 @@ AI is a tool. Expertise determines what it multiplies. LocalSetup brings enginee
[Read the complete story](ls/docs/WHY_LOCALSETUP.md) · [Explore the capabilities](ls/docs/FEATURES.md) · [Understand the security boundaries](SECURITY.md)
+## See LocalSetup in action
+
+Watch a Codex session work through a simulated coding task while LocalSetup's
+terminal companion shows commands, results, and layout controls. The full demo
+is silent and runs for about six minutes.
+
+[](https://cdn.cruxexperts.com/localsetup/demos/codex-observer-b8b5a3e9a5cf/demo.mp4)
+
+[Watch the full demo](https://cdn.cruxexperts.com/localsetup/demos/codex-observer-b8b5a3e9a5cf/demo.mp4).
+
## An operating layer around your tools
**Carry your context forward.** Keep project instructions, architectural decisions, and engineering standards in reviewable files. Reuse them across projects and supported clients instead of reconstructing them for each conversation.
@@ -38,7 +48,7 @@ AI is a tool. Expertise determines what it multiplies. LocalSetup brings enginee
| Fact | Value |
|---|---|
-| Current version | `4.89.4` |
+| Current version | `4.89.8` |
| Supported platforms | `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli` |
| Shipped skills | `115` |
| Workflow packages | `21` |
@@ -91,21 +101,19 @@ The guided installer explains the options, lets you select packages and supporte
Release included in this checkout
-**Version:** 4.89.4
+**Version:** 4.89.8
-## What's new in 4.89.4
+## What's new in 4.89.8
-LocalSetup 4.89.4 makes agent work easier to observe, preserves independently owned skills, and adapts test execution to resource pressure while keeping terminal operations under explicit owner control.
+LocalSetup 4.89.8 adds an animated README preview and full recorded demo on the dedicated public CDN, and uses the available runner CPUs for parallel CI shards.
-- **Follow native agent activity:** an owned terminal view shows bounded item metadata and operation state, with guarded recovery after transient read failures and an explicit history-gap signal.
-- **Keep terminal work under its owner:** managed shell operations retain process and session identity, private input remains operation-bound, and failures provide actionable feedback without granting new authority.
-- **Use independently owned skills:** select repository, personal, or framework origins explicitly; recorded snapshots and collision checks protect custom source during install, update, and rollback.
-- **See test pressure and progress:** the shared worker policy adapts to memory headroom and exposes versioned telemetry while the protected test scope retains its resource limits.
-- **Rejoin the right shell state:** attach, logs, input, and family instructions retain an explicitly selected private state root, including safely quoted paths in older status layouts.
-- **Find the practical starting point:** the homepage and framework guides lead with visible operations, privacy, and concrete engineering workflows, with detailed mechanisms in linked references.
+- **See LocalSetup in action:** the README shows a 15-second animated preview that links to a silent, six-minute Codex session demonstrating visible commands, results, and layout controls.
+- **Keep demo media separate:** reviewed, versioned public assets use the dedicated LocalSetup CDN bucket while the shared system bucket stays private.
+- **Use available CI capacity:** each hosted shard uses its runner's available logical CPUs, while the matrix schedules concurrent shard jobs up to its configured limit.
+- **Respect Git discovery boundaries:** a malformed Git file beyond a filesystem boundary does not prevent client state from using its global location, while malformed markers inside the boundary still fail closed.
-See the [4.89.4 release guide](ls/docs/releases/4.89.4.md) for compatibility, updating, and verification.
+See the [4.89.8 release guide](ls/docs/releases/4.89.8.md) for compatibility, updating, and verification.
diff --git a/VERSION b/VERSION
index b81c545e4..0c50b6b10 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.89.4
+4.89.8
diff --git a/ls/README.md b/ls/README.md
index 9b9493dc6..a645e85bf 100644
--- a/ls/README.md
+++ b/ls/README.md
@@ -1,6 +1,6 @@
# LocalSetup Framework Engine
-**Version:** 4.89.4
+**Version:** 4.89.8
`ls/` is the engine that makes the public LocalSetup promise real. It stores the framework code, shipped skills, workflow packages, platform templates, docs, tests, and install manifests that turn a repository into a portable agent workspace.
@@ -26,7 +26,7 @@ For the public product overview, start with the [root README](../README.md). Thi
LocalSetup-managed entries in consuming repositories are install output. Adapter directories may also contain project-owned skills, files, and symlinks; preserve that content in place. See [adapter ownership](docs/ADAPTER_OWNERSHIP.md).
-Read the [current release guide](docs/releases/4.89.4.md) for LocalSetup 4.89.4, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
+Read the [current release guide](docs/releases/4.89.8.md) for LocalSetup 4.89.8, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
## Install flow
diff --git a/ls/core/client_state/locator.py b/ls/core/client_state/locator.py
index 4d9713b34..7aa251c27 100644
--- a/ls/core/client_state/locator.py
+++ b/ls/core/client_state/locator.py
@@ -13,7 +13,7 @@
from .models import ClientStateError, GitContext, StateLocation
-_NOT_REPOSITORY = ("not a git repository", "outside repository")
+_NOT_REPOSITORY = ("not a git repository", "outside repository", "invalid gitfile format")
_STATE_CHILD = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
diff --git a/ls/core/test_plugin.py b/ls/core/test_plugin.py
index db73dacb5..303b6a134 100644
--- a/ls/core/test_plugin.py
+++ b/ls/core/test_plugin.py
@@ -104,8 +104,6 @@ def _configure_test_workers(config):
override = requested if type(requested) is int else None
workers = resolved_test_workers(override, project_root=project_root(config))
config.option.numprocesses = workers
- if config.getoption("ci_shards") > 1:
- config.option.numprocesses = 1
config.option.dist = "load"
except ValueError as exc:
raise pytest.UsageError(str(exc)) from exc
diff --git a/ls/core/test_resources.py b/ls/core/test_resources.py
index e33994ab0..90740c584 100644
--- a/ls/core/test_resources.py
+++ b/ls/core/test_resources.py
@@ -11,7 +11,7 @@
import sys
import uuid
-from .test_workers import default_test_workers, testing_configuration, resolved_test_workers
+from .test_workers import TEST_WORKERS_ENV, testing_configuration, resolved_test_workers
from .test_pressure import host_memory, host_reserve
from .test_telemetry import Telemetry
@@ -50,7 +50,8 @@ def resource_budget(project_root: Path | None = None) -> dict[str, int]:
min(values["MemTotal"], values["MemAvailable"]) * fraction // 100)
memory = min(memory, values["MemTotal"] * policy.get("physical_memory_percent", 95) // 100,
max(0, values["MemAvailable"] - host_reserve(values, policy)))
- cpu_percent = default_test_workers() * 100
+ cpu_percent = resolved_test_workers(project_root=project_root) * 100
+ explicit_workers = (TEST_WORKERS_ENV in os.environ or policy.get("workers", "auto") != "auto")
# Respect tighter enclosing cgroups, including hosted/container runners.
directory = cgroup_directory()
while directory != Path("/sys/fs"):
@@ -64,7 +65,8 @@ def resource_budget(project_root: Path | None = None) -> dict[str, int]:
if cpu_file.is_file():
quota, period = cpu_file.read_text().split()
if quota != "max":
- cpu_percent = min(cpu_percent, max(1, int(quota) * 100 // int(period) // 3))
+ parent_percent = max(1, int(quota) * 100 // int(period))
+ cpu_percent = min(cpu_percent, parent_percent if explicit_workers else max(1, parent_percent // 3))
if directory == Path("/sys/fs/cgroup"):
break
if directory.parent == directory:
diff --git a/ls/core/test_workers.py b/ls/core/test_workers.py
index d22a9a99e..b54a80f30 100644
--- a/ls/core/test_workers.py
+++ b/ls/core/test_workers.py
@@ -176,7 +176,7 @@ def test_workers_payload(
"configured_workers": configured["workers"] if configured is not None else None,
"shard_count": shard_count,
"shard_indices": list(range(shard_count)) if shard_count is not None else [],
- "workers_per_shard": 1 if shard_count is not None else None,
+ "workers_per_shard": workers if shard_count is not None else None,
"max_parallel": min(workers, shard_count) if shard_count is not None else workers,
"adaptive": configured.get("adaptive") if configured else None,
"local_queue_slots": workers,
diff --git a/ls/docs/COMMAND_REFERENCE.md b/ls/docs/COMMAND_REFERENCE.md
index 41fd78bf4..b88df69f4 100644
--- a/ls/docs/COMMAND_REFERENCE.md
+++ b/ls/docs/COMMAND_REFERENCE.md
@@ -948,7 +948,7 @@ localsetup test-workers --status --json
localsetup test-workers --watch
```
-The common `testing` section owns `workers` (`"auto"` or a positive integer) and `shard_count` (1–32), with legacy `[tool.localsetup.testing]` as a fallback. Auto resolves to `max(1, floor(available logical CPU cores / 3))`; an explicit value is capped at available logical cores and execution is further constrained by memory. `--workers` takes precedence over `LOCALSETUP_TEST_WORKERS`, which takes precedence over the project setting. JSON includes stable hosted CI partitions and their aggregate concurrency. The command reads `--target-directory` or `--repo` when supplied, otherwise the current project directory; the installed framework source is not substituted for that project.
+The common `testing` section owns `workers` (`"auto"` or a positive integer) and `shard_count` (1–32), with legacy `[tool.localsetup.testing]` as a fallback. Auto resolves to `max(1, floor(available logical CPU cores / 3))`; an explicit value is capped at available logical cores and execution is further constrained by memory. `--workers` takes precedence over `LOCALSETUP_TEST_WORKERS`, which takes precedence over the project setting. JSON includes stable hosted CI partitions, the per-runner worker request, and matrix job concurrency. Each isolated CI runner enforces its own CPU and memory limits; local concurrent runs share one guarded host budget. The command reads `--target-directory` or `--repo` when supplied, otherwise the current project directory; the installed framework source is not substituted for that project.
In this repository, plain `pytest ls/tests -q` loads the shared plugin. Local
execution has one queue per active worker; pending work is redistributed when
diff --git a/ls/docs/FEATURES.md b/ls/docs/FEATURES.md
index 0971f30f9..895f06736 100644
--- a/ls/docs/FEATURES.md
+++ b/ls/docs/FEATURES.md
@@ -29,7 +29,7 @@ implemented controls and prerequisites.
## Generated Facts
-- Current version: `4.89.4`
+- Current version: `4.89.8`
- Supported platforms: `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli`
- Shipped skills: `115`
- Workflow packages: `21`
diff --git a/ls/docs/README.md b/ls/docs/README.md
index ea45d4eb2..b68629c37 100644
--- a/ls/docs/README.md
+++ b/ls/docs/README.md
@@ -19,7 +19,7 @@ This is the public documentation map for LocalSetup. Start here when you want th
## Generated Facts
-- Current version: `4.89.4`
+- Current version: `4.89.8`
- Supported platforms: `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli`
- Shipped skills: `115`
- Workflow packages: `21`
@@ -55,7 +55,7 @@ This is the public documentation map for LocalSetup. Start here when you want th
| [Harness automation](HARNESS_AUTOMATION.md) | Opt-in heartbeat activation, typed LSCli profiles, reserved actions/controller accounting, runtime artifacts, cron gating and command-policy boundaries. |
-Read the [current release guide](releases/4.89.4.md) for LocalSetup 4.89.4, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
+Read the [current release guide](releases/4.89.8.md) for LocalSetup 4.89.8, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
The [4.4.0 guide](releases/4.4.0.md) covers the earlier context and package consolidation.
diff --git a/ls/docs/REPO_MAINTENANCE.md b/ls/docs/REPO_MAINTENANCE.md
index c3a677f0d..d31ecbea3 100644
--- a/ls/docs/REPO_MAINTENANCE.md
+++ b/ls/docs/REPO_MAINTENANCE.md
@@ -477,7 +477,7 @@ UV_CACHE_DIR=/tmp/localsetup-uv-cache uv run --locked python ls/tools/localsetup
- `pr-validation` is the required PR and merge-queue validation workflow.
- `generated docs and version sync` checks canonical version arithmetic before merge. `docs-sync` is called once as the prerequisite `documentation / generated docs drift` and owns generated-document drift, release prose, and documentation alignment; the version job does not regenerate the same files again.
-- `framework validation py3.12` is the aggregate result of the 12 configured isolated Python 3.12 shards, matching the supported Python floor. The prerequisite job reads common test policy through `test-workers` and queues one-worker shard jobs within its resolved `max_parallel` budget. Inexpensive version, audit, smoke, deterministic QC, catalog, branding, and architecture checks precede the shards. Each shard has a 60-minute deadline and stops on its first failure; all shards must pass.
+- `framework validation py3.12` is the aggregate result of the 12 configured isolated Python 3.12 shards, matching the supported Python floor. The prerequisite job asks `test-workers` for a hosted override equal to the runner's available logical CPU count; the resolved `max_parallel` limit admits that many shard jobs, up to the shard count. Each isolated job also requests a worker per available logical CPU on its own runner and passes that request into the resource guard, so its CPU quota matches the worker pool unless an enclosing CPU or memory limit is tighter. Local test runs retain their configured worker policy. Inexpensive version, audit, smoke, deterministic QC, catalog, branding, and architecture checks precede the shards. Each shard has a 60-minute deadline and stops on its first failure; all shards must pass.
The shards use `ubuntu-24.04` and verify tmux 3.4 before running tests, matching
the native family layout and retained-history qualification. A runner-label
migration must not silently change that contract. Qualify a newer tmux version
diff --git a/ls/docs/SKILLS.md b/ls/docs/SKILLS.md
index 9481c5f19..dca0fc143 100644
--- a/ls/docs/SKILLS.md
+++ b/ls/docs/SKILLS.md
@@ -4,10 +4,10 @@ version: 4.89
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 0d059193de13fb71f7f7235c6efd7a1b4fdfcb630f7110950d37ccabb58dfc76
---
# Shipped skills catalog
diff --git a/ls/docs/VERSIONING.md b/ls/docs/VERSIONING.md
index 9dc2ca54a..f0fbac0f3 100644
--- a/ls/docs/VERSIONING.md
+++ b/ls/docs/VERSIONING.md
@@ -11,7 +11,7 @@ LocalSetup uses the root `VERSION` file as the source of truth for the framework
## Current Version
- Source of truth: [`../../VERSION`](../../VERSION)
-- Current value: `4.89.4`
+- Current value: `4.89.8`
- Generated facts: [`_generated/facts.json`](_generated/facts.json)
## 4.x major-line lock and one-time numbering reconciliation
diff --git a/ls/docs/WORKFLOW_QUICK_REF.md b/ls/docs/WORKFLOW_QUICK_REF.md
index 146345b1b..373044246 100644
--- a/ls/docs/WORKFLOW_QUICK_REF.md
+++ b/ls/docs/WORKFLOW_QUICK_REF.md
@@ -4,10 +4,10 @@ version: 4.89
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 45ec2266b0d1fb7cda42e95eed2dac08569969331dac20774676e0380ad37caf
---
# Workflow quick reference
diff --git a/ls/docs/WORKFLOW_REGISTRY.md b/ls/docs/WORKFLOW_REGISTRY.md
index d11b9e65a..d5aa2e899 100644
--- a/ls/docs/WORKFLOW_REGISTRY.md
+++ b/ls/docs/WORKFLOW_REGISTRY.md
@@ -4,10 +4,10 @@ version: 4.89
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 7e4295af685adcaa9cea0ab89db9593e3daad12e29041c8914f6e35f1834c1db
---
# Workflow and module registry (LocalSetup)
diff --git a/ls/docs/_generated/artifact-registry.json b/ls/docs/_generated/artifact-registry.json
index 1e07aacf4..50514ac41 100644
--- a/ls/docs/_generated/artifact-registry.json
+++ b/ls/docs/_generated/artifact-registry.json
@@ -3,10 +3,10 @@
{
"artifact_sha256": "bed10d1fb964d318474266896970cea6e9b9e284e8c012e81f01fd584439af2c",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "assets/README.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -23,12 +23,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "337af9339a113c4af359ed7186de9a3a3535ebeb1018ffe5eeae7fc1b2646704",
+ "artifact_sha256": "1e6a205264a7d39333bfaf946711cb9882041d38c32426e743db17a9e6dcedf7",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/SKILLS.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -45,12 +45,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "2d204a83ef8f8368d5d57db1ae46465a37d233c0201b07e349a4ef0e471988d0",
+ "artifact_sha256": "068bd71e7d7f7c31987f34b04b87a25746f8b53eb7b028ccb00e49a342569ae9",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/WORKFLOW_QUICK_REF.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -67,12 +67,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "a2ff71bdf5c12b1aa627cf786eb7704c0a39d2acd374469dc8bee1f26fabd7c7",
+ "artifact_sha256": "af611098b7c05b9942b5021edbd43b01411d771e9b6f1999a8adcbaba57bc72d",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/WORKFLOW_REGISTRY.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -89,12 +89,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "03d348d31ea678d8770dd07bc78e5f53bfa0bb0beedd2eeeedd3de8028ac18fc",
+ "artifact_sha256": "073fc1823bd638b5e194dfb0ffda7166ff6c59f1ad4559c48c33500657619310",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/docs-alignment-summary.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -111,12 +111,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "469f46a35282c042772d3038b78b9256b3c11050f6fc2183416b2a30b226c0fb",
+ "artifact_sha256": "9f19060d6425d9d2726fbe034c550f18435c19b1def1c3af931dfe06d8d95c65",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/docs-asset-manifest.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -133,12 +133,12 @@
"type": "json"
},
{
- "artifact_sha256": "0e8c06b091f58453f3ba736b3173a26073936f5a30d44db1556baeb61a8623e5",
+ "artifact_sha256": "0e65aaaa846dcfb363c3fdd4b6f66889efee11798a147661a9a898000fbba85d",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/docs-audit-result.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -155,12 +155,12 @@
"type": "json"
},
{
- "artifact_sha256": "e55aa85c2b7e0a0a98ba4ed6477082016b7bfb93c29055dfa6ed5fa36eeb9153",
+ "artifact_sha256": "92ff3417c8c750c4e6873c953b29954dbb9ba35fb42b407e0f6a625ff4f52318",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/docs-inventory.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -177,12 +177,12 @@
"type": "json"
},
{
- "artifact_sha256": "d959ca8d2aa6ef2e40b40292d56d2507f91c7bf1541bca43daf95bd9d31a475a",
+ "artifact_sha256": "8cf999caa9078f7802ea1e3ff6d614be6e1c141871ddf8bbf0c336f1d6161e98",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/docs-truth-map.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -199,12 +199,12 @@
"type": "json"
},
{
- "artifact_sha256": "9dcbaa320442b0c99473c1765dce4ae0c291d11295782afc58aebe7909fbc321",
+ "artifact_sha256": "4a296a33813d98ceb05cba84ffd94cc853f98a202be32b2159efe6418dcb062e",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/facts.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -221,12 +221,12 @@
"type": "json"
},
{
- "artifact_sha256": "b0d550f08596ddbffaad5e9ce89a71d5f0dd6275b9e48fb6deb6b79be07d50a2",
+ "artifact_sha256": "00ec7f5cda8aef47fbc4cdf8067fa7af25cb139338ab6f74fbcc394f6556064a",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/implementation-file-map.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -243,12 +243,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "e5d81d1c309815782d9de59e70575b254183c906fe2e157ff1ef38bc5c36f8a6",
+ "artifact_sha256": "6ec94dbd42a42568e4abfa5438d84cb22da05e3b9c77d58e25b588a4742e9aa2",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/platform-adapters.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -265,12 +265,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "37cd18379ee9889df67377caa4a1e8a8a8859ee2f36d6a4710be90967e6e259d",
+ "artifact_sha256": "e2cfcab43b3ede3db4f00be83b2c26d7e570d66eddbc725aa8affb8ed9fa33aa",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/plugin-packs.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -287,12 +287,12 @@
"type": "json"
},
{
- "artifact_sha256": "fb0087ecdef6a5b2b097181a477c823101fbcb3103b6089fa3c6e335282274aa",
+ "artifact_sha256": "0174843f1ab14c875ec4552cb02e0cb09358aef08ff5863b6c60246084c8830e",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/plugin-packs.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -309,12 +309,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "b0600a18a84f292d7c99d4f168458085543d69476bc32be36db2ec3966673956",
+ "artifact_sha256": "d1ed9288cfd7a63fa7ca2b6de5c5db7d2a95ace8c8d3c31b48d369e785ad7382",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/skill-packs.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -331,12 +331,12 @@
"type": "markdown"
},
{
- "artifact_sha256": "dbfba479861dd8954aa3938933e2627f62ea2bcdf2418c7e95ffcc0064869168",
+ "artifact_sha256": "c7e15a99e8fa14454323d9939eb6465728af45931674df5df9a29241ed6bdb62",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/skill-taxonomy.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -353,12 +353,12 @@
"type": "json"
},
{
- "artifact_sha256": "1d545fc9681280df8812f40a234d4bbfc455c0b110114eae1406a1e950faddec",
+ "artifact_sha256": "3233f25ce8ff8a7b25862c70823fa8070031b613cf9a00eaf2b6f5f207d1276d",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/skill_aliases.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -375,12 +375,12 @@
"type": "json"
},
{
- "artifact_sha256": "c7345b6b11457abb4508d72bc195be01d14c8d758819cb10c05643df5543a5ff",
+ "artifact_sha256": "45ec152ec048cb03db9c4f5bdfda519e1336df952b80a699941bf3ff62d9532e",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/_generated/workflow-catalog.json",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -397,12 +397,12 @@
"type": "json"
},
{
- "artifact_sha256": "5affa2bc69968c953445a7a4102673c107edade7c2db7a84c83c44af42f6c33b",
+ "artifact_sha256": "e952d8afad0fd1775d3bd41ebafb4a9354127e15c1c487c83242f7fdd6976273",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"path": "ls/docs/migration/skill-alias-map.md",
- "provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_inputs": [
"VERSION",
"ls/skills",
@@ -421,16 +421,16 @@
],
"provenance": {
"artifact_path": "ls/docs/_generated/artifact-registry.json",
- "artifact_sha256": "7d58021377ac51f8e7e73ceb4c18094ed5c92bb42a0a202fdb36125900fda0db",
+ "artifact_sha256": "f5f20a02c8ceb2234a853766ae691663274831fcfbbfbd19f41613393d8651e9",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": 1
}
diff --git a/ls/docs/_generated/docs-alignment-summary.md b/ls/docs/_generated/docs-alignment-summary.md
index acd403fea..2308629df 100644
--- a/ls/docs/_generated/docs-alignment-summary.md
+++ b/ls/docs/_generated/docs-alignment-summary.md
@@ -4,11 +4,11 @@ version: 4.89
owner_package: docs-align
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: docs-align
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
-artifact_sha256: ac15be36686388564a695099e01acead6955ce3c623d0afd20ee3a296923e2bd
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
+artifact_sha256: ee72adc765d90e4a6684aaa3de4bd018319d09218a23ba76dc803f13e0f90043
---
# Documentation Alignment Summary
@@ -16,8 +16,8 @@ This page is generated from repository inventory, source-truth manifests, asset
| Signal | Value |
|---|---:|
-| Version | `4.89.4` |
-| Documentation files inventoried | 567 |
+| Version | `4.89.8` |
+| Documentation files inventoried | 568 |
| Immutable upstream documents | 64 |
| Shipped skills | 115 |
| Workflow packages | 21 |
diff --git a/ls/docs/_generated/docs-asset-manifest.json b/ls/docs/_generated/docs-asset-manifest.json
index 9e320908b..74dd70e29 100644
--- a/ls/docs/_generated/docs-asset-manifest.json
+++ b/ls/docs/_generated/docs-asset-manifest.json
@@ -252,14 +252,14 @@
"artifact_path": "ls/docs/_generated/docs-asset-manifest.json",
"artifact_sha256": "f757bc8e39f708af157ee6f777eaf0e044021005a62ce49546b214cd2e66e95a",
"emitter": "docs-align",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": "1.0"
}
diff --git a/ls/docs/_generated/docs-audit-result.json b/ls/docs/_generated/docs-audit-result.json
index 605b7032f..bd9435616 100644
--- a/ls/docs/_generated/docs-audit-result.json
+++ b/ls/docs/_generated/docs-audit-result.json
@@ -9,14 +9,14 @@
"artifact_path": "ls/docs/_generated/docs-audit-result.json",
"artifact_sha256": "e82619e42f31266261fa11fa954df7778b2d19b7f12d224a71a85ec1a8cf31a8",
"emitter": "docs-align",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": "1.0"
}
diff --git a/ls/docs/_generated/docs-inventory.json b/ls/docs/_generated/docs-inventory.json
index f8dfa5cac..aa5041e0a 100644
--- a/ls/docs/_generated/docs-inventory.json
+++ b/ls/docs/_generated/docs-inventory.json
@@ -326,8 +326,8 @@
"workflow"
],
"counts": {
- "docs": 567,
- "framework_docs": 120,
+ "docs": 568,
+ "framework_docs": 121,
"generated_docs": 5,
"platforms": 20,
"public_docs": 6,
@@ -1787,6 +1787,16 @@
"status": "ACTIVE",
"version": "4.89"
},
+ {
+ "class": "framework",
+ "has_frontmatter": true,
+ "managed_blocks": [],
+ "owner_package": "",
+ "owner_skill": "ls-github-release-publishing",
+ "path": "ls/docs/releases/4.89.8.md",
+ "status": "ACTIVE",
+ "version": "4.89"
+ },
{
"class": "framework",
"has_frontmatter": true,
@@ -6462,16 +6472,16 @@
],
"provenance": {
"artifact_path": "ls/docs/_generated/docs-inventory.json",
- "artifact_sha256": "028d4a38e7b9b43c61e6bfd4a28a9d13a52238fbaca7b60c45658aef87a595aa",
+ "artifact_sha256": "76f4c7bb482676a1c3bfdde18789855d3ad92640a9b1842a25ecb01052a7688e",
"emitter": "docs-align",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"repo": ".",
"schema_version": "1.0",
diff --git a/ls/docs/_generated/docs-truth-map.json b/ls/docs/_generated/docs-truth-map.json
index 2bf0ed448..2944c59f2 100644
--- a/ls/docs/_generated/docs-truth-map.json
+++ b/ls/docs/_generated/docs-truth-map.json
@@ -126,16 +126,16 @@
],
"provenance": {
"artifact_path": "ls/docs/_generated/facts.json",
- "artifact_sha256": "12e5e2645d62d3bf5cada7d9272c38afbc81a93bfb6a8d4623a2451a017a9cb8",
+ "artifact_sha256": "289cc98f152de1810cba9bb77855a8b319c9ce9a22dfe4477fa770a277b5def8",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"skill_count": 115,
"skills": [
@@ -2070,7 +2070,7 @@
"version": "1.0"
}
],
- "version": "4.89.4",
+ "version": "4.89.8",
"workflow_count": 21,
"workflows": [
{
@@ -2216,14 +2216,14 @@
"artifact_path": "ls/docs/_generated/skill-taxonomy.json",
"artifact_sha256": "3748c9f3ed45a4bb66d591327dbc435014bd7bc4c66dc1e04faff1f650a75a79",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": 1,
"skills": [
@@ -3931,16 +3931,16 @@
},
"provenance": {
"artifact_path": "ls/docs/_generated/docs-truth-map.json",
- "artifact_sha256": "797f94e763cc6dbcb6eefd5907dd8a6254b7297784148f006d4dcbdda16af142",
+ "artifact_sha256": "997344bc12e4ba8944435c8234285ae22bc8a47296a6b7d3bcd0e1b429c6af8f",
"emitter": "docs-align",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": "1.0",
"truths": {
@@ -4534,6 +4534,11 @@
"owner_skill": "ls-github-release-publishing",
"path": "ls/docs/releases/4.89.4.md"
},
+ {
+ "owner_package": "",
+ "owner_skill": "ls-github-release-publishing",
+ "path": "ls/docs/releases/4.89.8.md"
+ },
{
"owner_package": "",
"owner_skill": "ls-scrapling-url-extraction",
@@ -6282,14 +6287,14 @@
}
},
"version": {
- "facts_version": "4.89.4",
- "pyproject_version": "4.89.4",
+ "facts_version": "4.89.8",
+ "pyproject_version": "4.89.8",
"sources": [
"VERSION",
"pyproject.toml",
"ls/docs/_generated/facts.json"
],
- "value": "4.89.4"
+ "value": "4.89.8"
},
"workflow_catalog": {
"sources": [
diff --git a/ls/docs/_generated/facts.json b/ls/docs/_generated/facts.json
index adcba6950..412cc59b8 100644
--- a/ls/docs/_generated/facts.json
+++ b/ls/docs/_generated/facts.json
@@ -125,16 +125,16 @@
],
"provenance": {
"artifact_path": "ls/docs/_generated/facts.json",
- "artifact_sha256": "12e5e2645d62d3bf5cada7d9272c38afbc81a93bfb6a8d4623a2451a017a9cb8",
+ "artifact_sha256": "289cc98f152de1810cba9bb77855a8b319c9ce9a22dfe4477fa770a277b5def8",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"skill_count": 115,
"skills": [
@@ -2069,7 +2069,7 @@
"version": "1.0"
}
],
- "version": "4.89.4",
+ "version": "4.89.8",
"workflow_count": 21,
"workflows": [
{
diff --git a/ls/docs/_generated/implementation-file-map.md b/ls/docs/_generated/implementation-file-map.md
index d995a2173..e146ce7e9 100644
--- a/ls/docs/_generated/implementation-file-map.md
+++ b/ls/docs/_generated/implementation-file-map.md
@@ -1,11 +1,11 @@
---
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
-artifact_sha256: 83b38ad73c358bd0423e5f1b95e1e07bb1b909dda231d337576e4d05bbf81e81
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
+artifact_sha256: 76b9174ce8136e9752905cdacc4f771b6a2b7c88ebde52b771dd604279360d1e
---
# Implementation File Map
@@ -895,6 +895,8 @@ artifact_sha256: 83b38ad73c358bd0423e5f1b95e1e07bb1b909dda231d337576e4d05bbf81e8
| `keep` | `ls/docs/releases/4.84.6.md` |
| `keep` | `ls/docs/releases/4.89.4.json` |
| `keep` | `ls/docs/releases/4.89.4.md` |
+| `keep` | `ls/docs/releases/4.89.8.json` |
+| `keep` | `ls/docs/releases/4.89.8.md` |
| `keep` | `ls/docs/scrapling-cheat-sheet.md` |
| `keep` | `ls/lib/data_paths.sh` |
| `keep` | `ls/lib/deps.py` |
diff --git a/ls/docs/_generated/platform-adapters.md b/ls/docs/_generated/platform-adapters.md
index 3aba0c514..9997f5fda 100644
--- a/ls/docs/_generated/platform-adapters.md
+++ b/ls/docs/_generated/platform-adapters.md
@@ -1,10 +1,10 @@
---
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 5ce4949227d75f75f72c4ce822e3c0e7958e57a16acf1fdc16a050a35da5d212
---
# Platform Adapters
diff --git a/ls/docs/_generated/plugin-packs.json b/ls/docs/_generated/plugin-packs.json
index 8287b7e7c..9f79a93b8 100644
--- a/ls/docs/_generated/plugin-packs.json
+++ b/ls/docs/_generated/plugin-packs.json
@@ -398,14 +398,14 @@
"artifact_path": "ls/docs/_generated/plugin-packs.json",
"artifact_sha256": "dcc147156b64d08ffc43885ad115adaebc834cb516fad268eefaef31649bd9e5",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": 1
}
diff --git a/ls/docs/_generated/plugin-packs.md b/ls/docs/_generated/plugin-packs.md
index 3bd43b42f..b557710a0 100644
--- a/ls/docs/_generated/plugin-packs.md
+++ b/ls/docs/_generated/plugin-packs.md
@@ -1,10 +1,10 @@
---
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 0431f0f4b34af5061d3e66a48d1792b075f3e351d0f649963037c61f66252057
---
# Plugin Packs
diff --git a/ls/docs/_generated/skill-packs.md b/ls/docs/_generated/skill-packs.md
index 2ace52b13..22b632024 100644
--- a/ls/docs/_generated/skill-packs.md
+++ b/ls/docs/_generated/skill-packs.md
@@ -1,10 +1,10 @@
---
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: 07eff9baab9c71beb76cca0eb5b8db4deeab2bbf133c10cc4e6e4d821fc1fbbf
---
# Skill And Workflow Packs
diff --git a/ls/docs/_generated/skill-taxonomy.json b/ls/docs/_generated/skill-taxonomy.json
index efc69b010..51d9323a9 100644
--- a/ls/docs/_generated/skill-taxonomy.json
+++ b/ls/docs/_generated/skill-taxonomy.json
@@ -13,14 +13,14 @@
"artifact_path": "ls/docs/_generated/skill-taxonomy.json",
"artifact_sha256": "3748c9f3ed45a4bb66d591327dbc435014bd7bc4c66dc1e04faff1f650a75a79",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"schema_version": 1,
"skills": [
diff --git a/ls/docs/_generated/skill_aliases.json b/ls/docs/_generated/skill_aliases.json
index acfa9e928..28b220612 100644
--- a/ls/docs/_generated/skill_aliases.json
+++ b/ls/docs/_generated/skill_aliases.json
@@ -286,13 +286,13 @@
"artifact_path": "ls/docs/_generated/skill_aliases.json",
"artifact_sha256": "2bf995ed1b1425296a6b5576e4dcfe07508f1cb7db7672efb0a871cf32495291",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
}
}
diff --git a/ls/docs/_generated/workflow-catalog.json b/ls/docs/_generated/workflow-catalog.json
index 3d6d66c38..b6af897e7 100644
--- a/ls/docs/_generated/workflow-catalog.json
+++ b/ls/docs/_generated/workflow-catalog.json
@@ -4,14 +4,14 @@
"artifact_path": "ls/docs/_generated/workflow-catalog.json",
"artifact_sha256": "7acb2334f8508e596193cf01679eb5076c5d42213b0a8969f34366f028d4b165",
"emitter": "generate-docs",
- "framework_version": "4.89.4",
+ "framework_version": "4.89.8",
"schema_version": 1,
- "source_commit": "0b54b915ef889c4df5af8fb91b5071ab8a08396f",
+ "source_commit": "c6f57190a8e32b7258fc0f19630b43bbb1d2aa72",
"source_dirty": false,
- "source_provenance_hash": "c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67",
- "source_root_id": "625c8946f3b2197dc909625999cdfbfd5a79cc91e27858ffd322beb14298ab5b",
+ "source_provenance_hash": "4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379",
+ "source_root_id": "2f333faa00e87315ae10375138f36c465d2001f8ba87b01d2dc2461e03729cdf",
"source_tag": null,
- "source_tree_sha": "0f0bff0ea379099326ea0122cb00667e5aae354a"
+ "source_tree_sha": "2eff898ccdd7febef5f65f546916133ed9f80027"
},
"workflows": [
{
diff --git a/ls/docs/migration/skill-alias-map.md b/ls/docs/migration/skill-alias-map.md
index 53a956871..5dec08453 100644
--- a/ls/docs/migration/skill-alias-map.md
+++ b/ls/docs/migration/skill-alias-map.md
@@ -4,10 +4,10 @@ version: 4.89
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
- source_provenance_hash: c7a1a44680c79f1f4f42be2f60ab34171f9cc40925087b1b9b15b9063239de67
+ source_provenance_hash: 4a69988f70b3c2120bc69e254e4d633ccaf7936a98372f342bbf9ece12aec379
emitter: generate-docs
-framework_version: 4.89.4
-source_commit: 0b54b915ef889c4df5af8fb91b5071ab8a08396f
+framework_version: 4.89.8
+source_commit: c6f57190a8e32b7258fc0f19630b43bbb1d2aa72
artifact_sha256: f137d98acbf226ab31d8deefed1083ec684522db75b578cc2b4039acb3cad61b
---
# Skill Alias Map
diff --git a/ls/docs/releases/4.89.8.json b/ls/docs/releases/4.89.8.json
new file mode 100644
index 000000000..acb0a34a8
--- /dev/null
+++ b/ls/docs/releases/4.89.8.json
@@ -0,0 +1,46 @@
+{
+ "schema_version": 1,
+ "version": "4.89.8",
+ "source_commit": "9be5beec878ab3dc89429b45e2eed7f19dad82e8",
+ "baseline_tag": "v4.89.4",
+ "summary": "LocalSetup 4.89.8 adds an animated README preview and full recorded demo on the dedicated public CDN, and uses the available runner CPUs for parallel CI shards.",
+ "highlights": [
+ {
+ "text": "**See LocalSetup in action:** the README shows a 15-second animated preview that links to a silent, six-minute Codex session demonstrating visible commands, results, and layout controls.",
+ "evidence": [
+ "README.md"
+ ]
+ },
+ {
+ "text": "**Keep demo media separate:** reviewed, versioned public assets use the dedicated LocalSetup CDN bucket while the shared system bucket stays private.",
+ "evidence": [
+ "AGENTS.md"
+ ]
+ },
+ {
+ "text": "**Use available CI capacity:** each hosted shard uses its runner's available logical CPUs, while the matrix schedules concurrent shard jobs up to its configured limit.",
+ "evidence": [
+ ".github/workflows/pr-validation.yml",
+ "ls/docs/REPO_MAINTENANCE.md"
+ ]
+ },
+ {
+ "text": "**Respect Git discovery boundaries:** a malformed Git file beyond a filesystem boundary does not prevent client state from using its global location, while malformed markers inside the boundary still fail closed.",
+ "evidence": [
+ "ls/core/client_state/locator.py",
+ "ls/tests/test_client_state.py"
+ ]
+ }
+ ],
+ "compatibility": [
+ "The demo and CI changes do not alter installation or file formats. Git discovery recognizes invalid Git-file diagnostics beyond the current filesystem boundary; invalid markers within that boundary still block client state."
+ ],
+ "update": [
+ "Existing installations need no action for the demo. Open the repository README to watch the preview or the full recording.",
+ "[](https://cdn.cruxexperts.com/localsetup/demos/codex-observer-b8b5a3e9a5cf/demo.mp4)"
+ ],
+ "verification": [
+ "Anonymous HTTPS downloads returned the reviewed GIF (276,444 bytes; SHA-256 1e30aba8b37a9f1a0838c07c24762b687cb8e79a17186d3c75fb865d82fe2e22) and MP4 (15,405,349 bytes; SHA-256 b8b5a3e9a5cf29d062598b18b0181965ee26113de54dd777a2154026819b0942) with the expected media types. A video range request returned HTTP 206; the shared system bucket remained private.",
+ "Check the framework archive's `.sha256` checksum and `.cdx.json` SBOM sidecars with the release guide's `verify-release` command."
+ ]
+}
diff --git a/ls/docs/releases/4.89.8.md b/ls/docs/releases/4.89.8.md
new file mode 100644
index 000000000..24aabfd41
--- /dev/null
+++ b/ls/docs/releases/4.89.8.md
@@ -0,0 +1,42 @@
+---
+status: ACTIVE
+version: 4.89
+owner_skill: ls-github-release-publishing
+---
+
+# LocalSetup 4.89.8
+
+LocalSetup 4.89.8 adds an animated README preview and full recorded demo on the dedicated public CDN, and uses the available runner CPUs for parallel CI shards.
+
+## Highlights
+
+- **See LocalSetup in action:** the README shows a 15-second animated preview that links to a silent, six-minute Codex session demonstrating visible commands, results, and layout controls.
+- **Keep demo media separate:** reviewed, versioned public assets use the dedicated LocalSetup CDN bucket while the shared system bucket stays private.
+- **Use available CI capacity:** each hosted shard uses its runner's available logical CPUs, while the matrix schedules concurrent shard jobs up to its configured limit.
+- **Respect Git discovery boundaries:** a malformed Git file beyond a filesystem boundary does not prevent client state from using its global location, while malformed markers inside the boundary still fail closed.
+
+After publication, see the [release and downloads](https://github.com/CruxExperts/localsetup/releases/tag/v4.89.8) for release assets.
+
+## Compatibility
+
+The demo and CI changes do not alter installation or file formats. Git discovery recognizes invalid Git-file diagnostics beyond the current filesystem boundary; invalid markers within that boundary still block client state.
+
+## Update
+
+Existing installations need no action for the demo. Open the repository README to watch the preview or the full recording.
+
+[](https://cdn.cruxexperts.com/localsetup/demos/codex-observer-b8b5a3e9a5cf/demo.mp4)
+
+For installation and source refresh, read the [quickstart update instructions](../QUICKSTART.md#update). Adapter changes follow the [adapter ownership guide](../ADAPTER_OWNERSHIP.md).
+
+## Verify the download
+
+Anonymous HTTPS downloads returned the reviewed GIF (276,444 bytes; SHA-256 1e30aba8b37a9f1a0838c07c24762b687cb8e79a17186d3c75fb865d82fe2e22) and MP4 (15,405,349 bytes; SHA-256 b8b5a3e9a5cf29d062598b18b0181965ee26113de54dd777a2154026819b0942) with the expected media types. A video range request returned HTTP 206; the shared system bucket remained private.
+
+Check the framework archive's `.sha256` checksum and `.cdx.json` SBOM sidecars with the release guide's `verify-release` command.
+
+Download the framework archive with both its `.sha256` checksum and `.cdx.json` SBOM sidecars. Keep all three files in the same directory before running `verify-release`.
+
+```bash
+uv run --locked python ls/tools/localsetup.py --source-root . verify-release /path/to/localsetup-v4.89.8.tar.gz
+```
diff --git a/ls/skills/ls-localsetup-framework-changes/SKILL.md b/ls/skills/ls-localsetup-framework-changes/SKILL.md
index 6042aa55b..99f0ef4a4 100644
--- a/ls/skills/ls-localsetup-framework-changes/SKILL.md
+++ b/ls/skills/ls-localsetup-framework-changes/SKILL.md
@@ -88,7 +88,7 @@ git diff --check
- Run `audit-global-first` when global-first layout, lockfile, target-state, PowerShell removal, or source/target docs claims may be affected.
- Run focused tests and compliance checks for the code you changed before broad suites. Use the full pytest suite only as final consolidation for broad/shared runtime behavior, release/publish work, dependency changes, or explicit user requests. Resolve the permitted worker count with `localsetup test-workers`; [COMMAND_REFERENCE.md](../../docs/COMMAND_REFERENCE.md) owns its formula and aggregate-budget rule.
-The default aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Configured shards queue within that budget, with one worker per active shard. Concurrent test processes share the budget; they must not each claim it. Preserve stricter native execution limits.
+The default local aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Hosted shard jobs each use their isolated runner's CPU and memory budget; matrix concurrency bounds active jobs. Concurrent test processes on one host share that host's budget; they must not each claim it. Preserve stricter native execution limits.
For a serial illustrative pytest run, use `uv run --locked pytest -n 1 ls/tests -q`; use `localsetup test-workers` to query an appropriately bounded parallel run.
@@ -113,7 +113,7 @@ an understood failure, and stop automatic retries on an unexplained failure.
Complete source changes and the release record before generating final docs.
LocalSetup's hosted implementation derives its shard matrix and concurrency
-from the repository's testing configuration, with one worker per active shard
+from the repository's testing configuration, with each shard using the available CPUs of its isolated runner
and an all-shards success gate and exact-commit Actions evidence. The publishing workflow
checks that evidence before building instead of running the full suite again.
See [repository maintenance](../../docs/REPO_MAINTENANCE.md#validation-reuse).
diff --git a/ls/skills/ls-localsetup-project-context/SKILL.md b/ls/skills/ls-localsetup-project-context/SKILL.md
index a6ef44a65..db308c3c2 100644
--- a/ls/skills/ls-localsetup-project-context/SKILL.md
+++ b/ls/skills/ls-localsetup-project-context/SKILL.md
@@ -174,7 +174,7 @@ uv run --locked pytest ls/tests -q
Run focused pytest files or test functions and matching LocalSetup validators before the full suite. Resolve the permitted worker count with `localsetup test-workers`; [COMMAND_REFERENCE.md](../../docs/COMMAND_REFERENCE.md) owns its formula and aggregate-budget rule. Use the full suite as final consolidation for broad/shared runtime changes, release or publish work, dependency changes, or explicit user requests.
-The default aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Configured shards queue within that budget, with one worker per active shard. Concurrent test processes share the budget; they must not each claim it. Preserve stricter native execution limits.
+The default local aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Hosted shard jobs each have an isolated runner CPU and memory budget; matrix concurrency bounds active jobs. Concurrent test processes on one host share that host's budget; they must not each claim it. Preserve stricter native execution limits.
Before publish, run publish preflight against the intended base and keep generated docs/version sync with the repo tooling.
@@ -261,7 +261,7 @@ an understood failure, and stop automatic retries on an unexplained failure.
Complete source changes and the release record before generating final docs.
LocalSetup's hosted implementation derives its shard matrix and concurrency
-from the repository's testing configuration, with one worker per active shard
+from the repository's testing configuration, with each shard using the available CPUs of its isolated runner
and an all-shards success gate and exact-commit Actions evidence. The publishing workflow
checks that evidence before building instead of running the full suite again.
See [repository maintenance](../../docs/REPO_MAINTENANCE.md#validation-reuse).
diff --git a/ls/skills/ls-write-run-tests/SKILL.md b/ls/skills/ls-write-run-tests/SKILL.md
index 985b4722c..6c0139680 100644
--- a/ls/skills/ls-write-run-tests/SKILL.md
+++ b/ls/skills/ls-write-run-tests/SKILL.md
@@ -219,7 +219,7 @@ protocol starts cannot be mistaken for a failure of the protocol itself.
Complete source changes and the release record before generating final docs.
LocalSetup's hosted implementation derives its shard matrix and concurrency
-from the repository's testing configuration, with one worker per active shard
+from the repository's testing configuration, with each shard using the available CPUs of its isolated runner
and an all-shards success gate and exact-commit Actions evidence. The publishing workflow
checks that evidence before building instead of running the full suite again.
See [repository maintenance](../../docs/REPO_MAINTENANCE.md#validation-reuse).
diff --git a/ls/templates/codex/AGENTS.md b/ls/templates/codex/AGENTS.md
index 0a199a901..5f72ecf33 100644
--- a/ls/templates/codex/AGENTS.md
+++ b/ls/templates/codex/AGENTS.md
@@ -193,7 +193,7 @@ For long-running interactive work, give the human operator concise, scannable pr
- Work in the active repository by default. Do not create sibling clones, extra Git worktrees, PR-specific checkouts, release staging checkouts, or repo-shaped directories unless the user explicitly authorizes that specific path and purpose in the current task. If an exception is approved, record the path, branch, reason, expected lifetime, and cleanup command in the run ledger, then remove it when the approved purpose is complete.
- Keep validation proportional to risk. For tiny docs, policy, metadata, or one-line changes, prefer `git diff --check`, targeted syntax checks, or no executable test run when there is no executable surface. For LocalSetup framework work, run compliance and validation checks that match the changed code first, such as focused pytest files or test functions, `validate-catalog`, `validate-package-surface`, `doctor`, generated-doc drift checks, schema checks, and `git diff --check`. Do not add broad or repetitive tests merely to increase evidence; add tests only for behavior that can realistically regress.
- Use the full Python suite only as final consolidation verification for broad/shared runtime changes, release or publish work, dependency changes, or explicit user requests. Resolve the permitted worker count with `localsetup test-workers`; the generated command reference owns its formula and aggregate-budget rule. Do not use full pytest as the default first-pass validation for routine daily edits.
-- Unit-test concurrency policy: The default aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Configured shards queue within that budget, with one worker per active shard. Concurrent test processes share the budget; they must not each claim it. Preserve stricter native execution limits.
+- Unit-test concurrency policy: The default local aggregate test-worker budget is `max(1, floor(available logical CPU cores / 3))`. A configured positive integer override may increase or decrease that budget, with a hard cap of the available logical CPU count. Resolve and enforce the budget in code from the selected repository configuration; agents and users edit settings, not scheduling calculations. Hosted shard jobs each use their isolated runner's CPU and memory budget; matrix concurrency bounds active jobs. Concurrent test processes on one host share that host's budget; they must not each claim it. Preserve stricter native execution limits.
- On resume, recalculate the budget from currently available CPUs. Inspect inherited worker overrides and do not carry forward a stale lower setting when the user requests the full formula-based budget.
## Reuse Validation Evidence
diff --git a/ls/tests/test_ci_sharding.py b/ls/tests/test_ci_sharding.py
index 8ac85a8fb..a59bb249b 100644
--- a/ls/tests/test_ci_sharding.py
+++ b/ls/tests/test_ci_sharding.py
@@ -131,7 +131,10 @@ def test_configured_local_pytest_uses_shared_budget_and_group_queue(monkeypatch)
assert config.option.numprocesses == 2
config.getoption = lambda name: {"ci_shards": 12}[name]
shard_hooks._configure_test_workers(config)
- assert config.option.numprocesses == 1
+ assert config.option.numprocesses == 2
+ config.option.numprocesses = None
+ shard_hooks._configure_test_workers(config)
+ assert config.option.numprocesses == 4
monkeypatch.setattr(shard_hooks, "testing_configuration",
lambda _root: {"workers": 7, "shard_count": 1})
config.getoption = lambda name: {"ci_shards": 1}[name]
@@ -164,7 +167,12 @@ def test_ci_workflow_uses_project_policy_for_shards_and_aggregate_parallelism():
assert "test_policy: ${{ steps.test-policy.outputs.json }}" in workflow
assert "max-parallel: ${{ fromJSON(needs.framework-prerequisites.outputs.test_policy).max_parallel }}" in workflow
assert "shard: ${{ fromJSON(needs.framework-prerequisites.outputs.test_policy).shard_indices }}" in workflow
- assert "pytest -n 1 ls/tests" in workflow
+ assert 'pytest -n "$(nproc)" ls/tests' in workflow
+ parsed = yaml.safe_load(workflow)
+ pytest_step = next(step for step in parsed["jobs"]["framework-validation"]["steps"]
+ if step["name"] == "Run pytest")
+ assert pytest_step["env"]["LOCALSETUP_TEST_WORKERS"] == (
+ "${{ fromJSON(needs.framework-prerequisites.outputs.test_policy).workers_per_shard }}")
@pytest.mark.parametrize("cancelled,prerequisites,reused,run", [
diff --git a/ls/tests/test_client_state.py b/ls/tests/test_client_state.py
index 944ec9d58..644e6d4a5 100644
--- a/ls/tests/test_client_state.py
+++ b/ls/tests/test_client_state.py
@@ -473,8 +473,9 @@ def test_broken_git_marker_never_falls_back_to_global_state(
assert not (home / ".codex" / "state").exists()
+@pytest.mark.parametrize("new_git_error", [False, True])
def test_git_marker_discovery_stops_before_cross_filesystem_parent(
- tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch, new_git_error: bool
) -> None:
foreign_parent = tmp_path / "foreign-filesystem"
foreign_parent.mkdir()
@@ -494,6 +495,16 @@ def mounted(path: Path, *args, **kwargs):
return stat_with_dev(result, foreign_device) if path == foreign_parent else result
monkeypatch.setattr(Path, "stat", mounted)
+ if new_git_error:
+ original_git = locator._git
+
+ def newer_git(path: Path, *args: str):
+ if args == ("rev-parse", "--is-inside-work-tree"):
+ return subprocess.CompletedProcess(
+ ["git"], 128, "", "fatal: invalid gitfile format: foreign/.git")
+ return original_git(path, *args)
+
+ monkeypatch.setattr(locator, "_git", newer_git)
location = resolve_state_location(
ROOT, "codex/codex-cli", cwd=cwd, home=home, scope="auto"
)
@@ -503,6 +514,20 @@ def mounted(path: Path, *args, **kwargs):
assert not location.root.exists()
+def test_invalid_gitfile_within_discovery_boundary_fails_closed(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ repo = tmp_path / "invalid"
+ repo.mkdir()
+ (repo / ".git").write_text("gitdir: ../missing\n", encoding="utf-8")
+ monkeypatch.setattr(locator, "_git", lambda *_args: subprocess.CompletedProcess(
+ ["git"], 128, "", "fatal: invalid gitfile format: invalid/.git"))
+
+ with pytest.raises(ClientStateError) as failure:
+ probe_git_context(repo)
+ assert failure.value.code == "git_probe_failed"
+
+
def test_git_marker_discovery_stat_uncertainty_fails_closed(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
diff --git a/ls/tests/test_path_contract.py b/ls/tests/test_path_contract.py
index f02201e90..84d33de1c 100644
--- a/ls/tests/test_path_contract.py
+++ b/ls/tests/test_path_contract.py
@@ -144,7 +144,7 @@ def test_test_worker_project_policy_and_override_precedence(tmp_path: Path) -> N
assert resolved_test_workers("8", cpu_count=9, env={"LOCALSETUP_TEST_WORKERS": "4"},
project_root=tmp_path) == 8
payload = workers_payload(cpu_count=9, env={}, project_root=tmp_path)
- assert (payload["workers_per_shard"], payload["max_parallel"], payload["shard_count"]) == (1, 7, 12)
+ assert (payload["workers_per_shard"], payload["max_parallel"], payload["shard_count"]) == (7, 7, 12)
assert payload["worker_source"] == "project_configuration"
assert workers_payload(cpu_count=9, env={"LOCALSETUP_TEST_WORKERS": "3"},
project_root=tmp_path)["worker_source"] == "environment"
diff --git a/ls/tests/test_test_resources.py b/ls/tests/test_test_resources.py
index 41ff39be8..58283447d 100644
--- a/ls/tests/test_test_resources.py
+++ b/ls/tests/test_test_resources.py
@@ -67,6 +67,7 @@ def missing():
def test_budget_binds_selected_project_and_respects_parent_headroom(tmp_path, monkeypatch):
+ monkeypatch.delenv("LOCALSETUP_TEST_WORKERS", raising=False)
project = tmp_path / "project"
project.mkdir()
(project / "pyproject.toml").write_text("[tool.localsetup.testing]\nmemory_percent=25\ntasks_max=64\n")
@@ -82,6 +83,9 @@ def test_budget_binds_selected_project_and_respects_parent_headroom(tmp_path, mo
if p == Path("/proc/meminfo") else original(p, *a, **k))
budget = safety.resource_budget(project)
assert budget == {"memory_bytes": 768 * 1024**2, "cpu_quota_percent": 66, "tasks": 64}
+ monkeypatch.setenv("LOCALSETUP_TEST_WORKERS", "4")
+ assert safety.resource_budget(project)["cpu_quota_percent"] == 200
+ monkeypatch.delenv("LOCALSETUP_TEST_WORKERS")
(group / "memory.current").write_text(str(3 * 1024**3))
with pytest.raises(RuntimeError, match="insufficient"):
safety.resource_budget(project)
diff --git a/pyproject.toml b/pyproject.toml
index 4c8a3d966..79f64a9e1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "localsetup"
-version = "4.89.4"
+version = "4.89.8"
description = "Visible operations, shared context, and controlled workflows for AI agent tools"
license = "PolyForm-Noncommercial-1.0.0"
license-files = ["LICENSE", "ls/licenses/MIT-legacy.txt"]
diff --git a/uv.lock b/uv.lock
index f8a19f953..155c7b696 100644
--- a/uv.lock
+++ b/uv.lock
@@ -560,7 +560,7 @@ wheels = [
[[package]]
name = "localsetup"
-version = "4.89.4"
+version = "4.89.8"
source = { editable = "." }
dependencies = [
{ name = "anyio" },