docs(openspec): Propose local-rule-routing change - #23
Merged
Conversation
Add the change contract for a local-first rule-routing layer: a deterministic detect command plus route/existing/static/remote recipes that keep authoring on-device and gate the login wall behind reasonable confidence with a confirm-before-service fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `taskless detect --json`: an offline, deterministic scan of the repo for configured linters (config files, pyproject tool tables, package deps), inferred languages/frameworks, and the repo's own rule styles. No LLM, no network, no auth — it emits stable signal JSON to feed the routing recipe. Includes a focused scanner module, output schema, and integration tests covering detection, language/framework inference, no-packaged-rule-claims, and the offline/no-auth contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the four routing recipes the skill fetches as the rule-authoring front door. `route` runs detect, requires the agent to write its rationale before naming a destination, commits local on reasonable confidence, asks when multiple paths fit, and treats try-verify-escalate as a failure fallback that prompts-and-confirms before spending a generation. `existing` authors in a detected linter's dialect (repo-first knowledge, web fallback, author-only). `static` authors a verified local ast-grep rule in the canonical on-disk shape, cleaning up an abandoned candidate on escalation. `remote` collects inputs and delegates to the rule create backend, letting the service decide static vs runtime. Recipes are auto-embedded via the existing import.meta.glob step and all four resolve through `taskless help <topic>`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Defines a spec-driven OpenSpec contract for a local-first rule-authoring “routing front door” in Taskless, centered around an offline detect signal scan and a help-recipe based classifier (route) that prefers local authoring paths (existing / static) and escalates to the service (remote) only with explicit user confirmation when needed.
Changes:
- Adds a new OpenSpec change set (
local-rule-routing) with proposal/design docs and a spec-driven manifest. - Introduces CLI requirements for
taskless detect --jsonand for theroute/existing/static/remotehelp-recipe layer (including rationale-first and confirmation-gated escalation semantics). - Updates the
skill-tasklesscontract to engage routing when a linter is named (instead of suppressing) and to route rule-authoring via the newroutetopic.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| openspec/changes/local-rule-routing/specs/skill-taskless/spec.md | Updates the skill triggering and routing contract to use the new routing front door. |
| openspec/changes/local-rule-routing/specs/cli-rule-routing/spec.md | Specifies the routing recipe contract and the three destinations (existing/static/remote). |
| openspec/changes/local-rule-routing/specs/cli-help/spec.md | Requires help-topic registration + telemetry for routing topics. |
| openspec/changes/local-rule-routing/specs/cli-detect/spec.md | Specifies an offline, deterministic detect --json signal scan + stable JSON output requirement. |
| openspec/changes/local-rule-routing/proposal.md | High-level motivation, scope, and impact summary for the change stack. |
| openspec/changes/local-rule-routing/design.md | Detailed design decisions, constraints, and routing rationale/fallback model. |
| openspec/changes/local-rule-routing/.openspec.yaml | Declares the change set as spec-driven with creation date. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
List route/existing/static/remote under an "Authoring recipes" section of the `taskless help` no-arg index so an agent can discover the rule-authoring front door. The existing help command already emits help_<topic> intent telemetry generically, so the routing topics inherit it. Add integration tests for index listing and topic resolution, plus an in-process test asserting help_route/existing/static/remote capture. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverse the named-tool suppression: naming a linter (eslint, ruff, biome, ast-grep) now ENGAGES the skill's routing flow via `taskless help route` instead of quieting it. Replace the "Quiet suggestion" section with a route-through-route body that forbids fetching `rule create` directly and adds no linter knowledge, and relax the install gate so the `existing` path (which only reads the repo) is not blocked when `.taskless/` is absent. Description measures 835/1024 chars. Skill version is build-locked to the package version, so a minor changeset drives the bump rather than a hand-edited mismatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a labeled request→route calibration dataset for the route recipe covering both failure directions: over-claim (Taskless grabbing a packaged/formatter job that should stay `existing`) and over-escalate (a locally-solvable request wrongly sent to the login-gated service that should stay `static`), plus genuine `remote` cases. The route decision is agent-made by following help/route.txt, so the coverage test guards the dataset's balance across routes and traps rather than running a code classifier. Closes out the change: openspec validate passes, full CLI suite green, detect + routing recipes smoke-tested end-to-end. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thecodedrift
marked this pull request as ready for review
June 11, 2026 23:48
Resolve Copilot review on PR #23: - Drop the "provably cannot be built locally" framing in the proposal; it set a stricter bar than the confidence-gated contract. Login is suggested when route is not reasonably confident a rule is locally solvable, or when a confident local attempt fails and the user confirms. - Tighten the cli-rule-routing spec so routing distinguishes three states: confident-local, reasonable-belief-not-local (-> remote), and genuine uncertainty (-> ask). Mere uncertainty no longer reads as a remote trigger. - Reference the canonical `npx @taskless/cli help route` invocation in the skill-taskless spec instead of a bare `taskless` binary name. - Fix Markdown inline-code spans that were split across line breaks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reword the cli-detect spec: detect validates its --json output against an internal Zod schema before printing (same as info/check), rather than a "published output schema." The schema is an internal contract and detect exposes no --schema mode. Resolves the remaining Copilot note on PR #23. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a JSON example of `detect --json` output to the route recipe's scan step, so the agent sees the shape it consumes (linters, languages, frameworks, ruleStyles) — parity with how info/check recipes show their --json output. Addresses review feedback on the routing layer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tighten route.txt step 3 to match the cli-rule-routing spec: choosing `remote` requires a positive belief the request cannot be solved locally (cross-file/semantic), not mere lack of confidence. Genuine uncertainty routes to a clarifying question, never to a generation-spending remote. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat/local-rule-routing: docs(openspec): Clarify detect output schema is internal, not published docs(openspec): Address review feedback on local-rule-routing contract
* feat/local-rule-detect: docs(openspec): Clarify detect output schema is internal, not published docs(openspec): Address review feedback on local-rule-routing contract
* feat/local-rule-recipes: docs(cli): Align route recipe with the three-state contract docs(cli): Show detect output shape in the route recipe docs(openspec): Clarify detect output schema is internal, not published docs(openspec): Address review feedback on local-rule-routing contract
* feat/local-rule-help: docs(cli): Align route recipe with the three-state contract docs(cli): Show detect output shape in the route recipe docs(openspec): Clarify detect output schema is internal, not published docs(openspec): Address review feedback on local-rule-routing contract
* feat/local-rule-skill: docs(cli): Align route recipe with the three-state contract docs(cli): Show detect output shape in the route recipe docs(openspec): Clarify detect output schema is internal, not published docs(openspec): Address review feedback on local-rule-routing contract
Address review on PR #24: - Guard package.json dependency parsing: a malformed field (array/string/ null) no longer yields bogus dependency names via Object.keys. - Match pyproject tool tables exactly: `[tool.ruff]` or a nested `[tool.ruff.lint]`, never a similarly-prefixed sibling like `[tool.ruff-lsp]`. Anchored at line start to avoid value matches. - Rename the linter `configFiles` output field to `evidence`: it holds config paths AND non-path markers (pyproject tables, package deps), so the old name/contract was misleading. - Drop the divergent unused detect errorSchema; the error path emits the standard `{ ok, code, message }` envelope via makeErrorEnvelope. - Run detect tests with telemetry disabled (DO_NOT_TRACK), keeping the offline scan path hermetic, and add coverage for the table-prefix and malformed-manifest cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR #25 review: - remote.txt: stop advertising runtime rules / check.ts as current behavior, since runtime-rule support isn't shipped end-to-end yet. Reframe the recipe around gathering inputs and delegating to `rule create`; the service owns rule-type selection and today writes ast-grep rules under .taskless/rules/. - static.txt: instruct writing the matching `id` field in the test file (alongside valid/invalid), as rule create --anonymous and the CLI's test-file writer do and ast-grep test filtering expects. - route.txt: update the detect output example to the renamed `evidence` field (follows the detect rename on PR #24). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR #27 review: - The changeset targeted the private, unpublished root `@taskless/skills` package, which produces no release and is overwritten by sync-skill-versions. Target `@taskless/cli` — the published package and the version source of truth that skill metadata.version is locked to. - Add `stylelint` to the skill body's example tool list so it matches the description's list. - Update the tasks.md 4.3 note to describe the real release mechanism (@taskless/cli version drives the skill version via sync-skill-versions). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat/local-rule-detect: fix(cli): Harden detect against malformed manifests and false positives
* feat/local-rule-recipes: docs(cli): Address review on routing recipes fix(cli): Harden detect against malformed manifests and false positives
* feat/local-rule-help: docs(cli): Address review on routing recipes fix(cli): Harden detect against malformed manifests and false positives
* feat/local-rule-skill: fix(skill): Target @taskless/cli in the changeset; align tool lists docs(cli): Address review on routing recipes fix(cli): Harden detect against malformed manifests and false positives
PR #28 review: - The trap-coverage test asserted the traps were declared but never verified each trap has at least one case, so the dataset could silently stop covering a failure direction (e.g. under-engage) while the test stayed green. Now every declared trap must have >= 1 case, and under-engage cases are asserted to route to `existing`. - Fix the tasks.md note to point at the real fixture/test paths under packages/cli/test/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All 25 tasks are complete, so finalize the change on the tip of the stack: apply the delta specs into the main specs (new cli-detect and cli-rule-routing capabilities; cli-help and skill-taskless updates) and move the change to openspec/changes/archive/2026-06-12-local-rule-routing/. With no unarchived change remaining, the PR OpenSpec Archive Check passes for the final merged state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the frameworks field from the detect output example and note the scan is monorepo-aware (evidence can carry a sub-package path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Mirror the detect contract changes into the synced cli-detect capability spec: drop frameworks, add the languages-only / per-language-manifest / monorepo scenarios. - Add a README testing section clarifying the two kinds of test: the local vitest suite (deterministic, no agent) versus the route-honesty dataset, whose automated test only guards the fixture structure while the actual agent evaluation is a separate manual calibration step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat/local-rule-recipes: docs(cli): Update route recipe detect example for the new shape
* feat/local-rule-help: docs(cli): Update route recipe detect example for the new shape
* feat/local-rule-skill: docs(cli): Update route recipe detect example for the new shape
detect recognized these languages but reported zero linters for them. Fill the obvious gaps with config-file signals: golangci-lint (Go), Clippy (Rust), and PHPStan / PHP_CodeSniffer / Psalm (PHP). Still tool-level signal, no rule catalog — consistent with the D3 non-goal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat/local-rule-detect: feat(cli): Add linters for already-detected Go, Rust, and PHP
* feat/local-rule-recipes: feat(cli): Add linters for already-detected Go, Rust, and PHP
* feat/local-rule-help: feat(cli): Add linters for already-detected Go, Rust, and PHP
* feat/local-rule-skill: feat(cli): Add linters for already-detected Go, Rust, and PHP
When the restructure-cli-telemetry change lands, detect/help must conform to the cli_run + cli_help taxonomy. Mark both sites with a shared TODO(telemetry-taxonomy) tag: drop the silent cli_detect capture in detect.ts (the easy-to-miss half) and convert the help_<topic> assertions (which fail on rebase, so they self-surface). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reference the tracking issue (#39) from both reconciliation anchors so the context lives next to the code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* main: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
* feat/local-rule-routing: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
* feat/local-rule-detect: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
* feat/local-rule-recipes: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
* feat/local-rule-help: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
* feat/local-rule-skill: (21 commits)
refactor(cli): Uppercase the acronym in CLIConfig
refactor(cli): Uppercase the acronym in CLIErrorEnvelope too
fix(cli): Carry the CLIErrorCode rename into auth.ts
docs(openspec): Uppercase CLIError/CLIErrorCode in the change contract
docs(openspec): Uppercase CLIError/CLIErrorCode in the analytics spec
refactor(cli): Uppercase the CLI acronym in CliError/CliErrorCode
docs(openspec): Sync corrected check/help spec into the archived capability
fix(cli): Resolve cli_run identity at invocation start, not end
test(cli): Prove help_* removal once via a source scan, not per-test
test(cli): Assert no legacy help_* event on served-topic and index paths
refactor(cli): Single-pass check counts; robust cli_installed assertion
fix(cli): Only emit cli_rule_created/improved when rules are written
fix(cli): Resolve cli_run identity fresh; tighten cli_error + drop cli_version
docs(openspec): Address review on the telemetry contract
ci(openspec): Skip the archive check on non-tip stacked PRs
chore(openspec): Archive restructure-cli-telemetry and sync specs
feat(cli): Collapse help_* into cli_help { topic }; drop cli_info
feat(cli): Concrete auth + lifecycle events; drop start/_completed pairs
feat(cli): Emit concrete rule events; drop rule start/_completed pairs
feat(cli): Emit cli_run once per invocation from the runner
...
The telemetry restructure has landed on main, so the detect stack now adopts
the new event taxonomy:
- detect.ts: drop the bespoke cli_detect capture. detect is read-only, so the
per-invocation cli_run denominator (from the runner) covers it. Removes the
now-unused getTelemetry import.
- help-routing-telemetry.test.ts: the per-topic help_<topic> events collapsed
into cli_help { topic }; assert cli_help for the routing topics.
Clears both TODO(#39) anchors. Closes #39.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conform detect.ts to the cli_ taxonomy now on main: detect is read-only and rides on cli_run, so the bespoke cli_detect capture and its getTelemetry import go. Matches the tip's #39 resolution so the branch is green/consistent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
help.ts now emits cli_help { topic } instead of per-topic help_<topic> (the
taxonomy on main). Update the routing-topic assertions to match so this branch
is green/consistent with the tip's #39 resolution.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat/local-rule-detect: chore(cli): Drop cli_detect on the detect branch (telemetry taxonomy)
* feat/local-rule-recipes: chore(cli): Drop cli_detect on the detect branch (telemetry taxonomy)
* feat/local-rule-help: test(cli): Assert cli_help for routing topics (telemetry taxonomy) chore(cli): Drop cli_detect on the detect branch (telemetry taxonomy)
* feat/local-rule-skill: test(cli): Assert cli_help for routing topics (telemetry taxonomy) chore(cli): Drop cli_detect on the detect branch (telemetry taxonomy)
feat(cli): Add deterministic detect command for rule routing
…local-rule-routing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Establish the OpenSpec change contract for a local-first rule-routing layer in the Taskless CLI and skill.
Today authoring a rule routes straight to the login-gated
rule create, which runs generation off the developer's machine, and the skill suppresses itself whenever a user names a linter (eslint, ruff, biome) — stepping back from exactly the requests where Taskless could help author the rule in that tool's dialect. This change defines a routing front door that keeps authoring on-device whenever possible and only escalates to the service (with explicit confirmation) when a rule genuinely can't be built locally.The contract introduces:
cli-detect— a deterministic, offlinetaskless detect --jsonsignal scan.cli-rule-routing—route/existing/static/remoterecipes with a confidence-gated contract: reason before routing, commit local on reasonable confidence, and treat try-verify-escalate as a failure fallback that prompts-and-confirms before spending a generation.cli-help(modified) — register the four routing topics + intent telemetry.skill-taskless(modified) — reverse named-tool suppression so naming a linter engages routing; the 1024-char description ceiling is a first-class gating constraint.This change deliberately does not define static-vs-runtime classification — that cut is owned upstream by the Runtime Rules project (TSKL) and lives behind
remote.routeonly decides local-vs-remote.This is the base of a stack; implementation PRs land on top of it group by group.
Refs TSKL Runtime Rules
Stack generated by Git Town