Skip to content

fix(init): keep the Claude Code trust entry current, and stop chaining Taskless commands - #528

Merged
theCodeDrift merged 7 commits into
mainfrom
refresh-global-trust-entry
Oct 17, 2026
Merged

theCodeDrift merged 7 commits into
mainfrom
refresh-global-trust-entry

Conversation

@theCodeDrift

@theCodeDrift theCodeDrift commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

An onboarding agent in Claude Code's auto mode was refused even though the user had a Taskless CLI: entry in autoMode.allow:

Bash(S=<scratchpad> && mkdir -p $S && npx @taskless/cli@0… )
  ⎿  Denied by auto mode classifier ∙ [Untrusted Code Integration]

It had wrapped the pinned call in shell plumbing to stash its output, so the line no longer started with the call the entry describes. The skill's fallback then told the user to add the entry they already had. Their entry was also hand-copied older text, and since a present entry was never rewritten, no install or update could fix it.

What changes

  • Skill body: run every Taskless command on a line of its own beginning with the pinned invocation: no VAR=, cd, mkdir, &&, ;, pipe, or redirect. Files a recipe needs go through the agent's file tools. A refused line that combined the call with anything else is rerun once on its own. When the current entry is already in ~/.claude/settings.json, the agent says so instead of asking for it again.
  • Entry text: one added sentence. The pinned call stays covered when the same line sets a variable, changes or creates a directory, or redirects the call's output to a file; every other command on the line is judged on its own. Pipes are deliberately not covered.
  • Stale entries are replaced on install/update. The Taskless CLI: label is ours: an entry carrying it with any other text is stale. The wizard (bare npx @taskless/cli, which is how a person both installs and updates) shows REPLACE (global): and swaps it in place, keeping list order, under the one existing confirmation. Declining leaves the file byte-identical. Only the first labelled string is replaced, and an unlabelled string is never treated as ours.
  • init still never writes outside the project. It warns that the entry is out of date, and init --json reports globalTrust[].state: "stale". The init recipe documents the new state.

The skill body reached exactly 150 lines, its old cap, so skill-taskless raises the cap to 200 rather than compressing guidance an agent acts on.

Checks

  • pnpm typecheck, pnpm lint: pass
  • pnpm --filter @taskless/cli test: 128 files, 2372 tests pass
  • OpenSpec change refresh-global-trust-entry archived on this PR. The scenario check from CLAUDE.md shows no scenario dropped from agent-global-trust or skill-taskless.

@theCodeDrift

Copy link
Copy Markdown
Member Author

@claude /review

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @theCodeDrift's task in 2m 58s —— View job


Review: fix(init): keep the Claude Code trust entry current, and stop chaining Taskless commands

Review mode: incremental — read 0 prior review thread(s) before reviewing. .prior-review.json contains no review threads and no prior review summaries for this PR (only the triggering @claude /review comment itself). This is the first review of this PR, so the full diff was assessed from scratch.

Scope reviewed: full gh pr diff (18 files), with whole-file reads of packages/cli/src/install/global-trust.ts, packages/cli/src/install/permissions.ts (the shared set/modify machinery), packages/cli/src/wizard/index.ts, packages/cli/src/wizard/steps/summary.ts, skills/taskless/SKILL.md, packages/cli/src/agent/init.md, and the test files touched (global-trust.test.ts, wizard-integration.test.ts, init-no-interactive.test.ts, installed-documentation.test.ts).

Overall: this is a careful, well-tested change. The stale state threads consistently through inspect() → syncGlobalTrust → needsWrite() → describeGlobalTrust/globalTrustWarnings → the wizard summary and init --json/prose output, and I didn't find a call site that still only branches on "absent" where "stale" should also apply (wizard/index.ts's write-gate and summary.ts's editsSettings both correctly switched to needsWrite()). The in-place replace via set(current, [...trust.key, index], GLOBAL_TRUST_ENTRY) relies on jsonc-parser's modify replacing (not inserting) at an existing index, which matches the "replace only the first labelled entry, leave the rest" tests. Test coverage for the new stale paths (unit, wizard end-to-end incl. decline/byte-identical, non-interactive JSON + stderr) is thorough.

[New] Minor doc drift in packages/cli/src/agent/init.md (not touched by this PR's diff, so missed rather than introduced): the prose-mode description at line ~103–106 still reads "a warning for each missing global trust entry", but globalTrustWarnings() now also warns for stale entries (via needsWrite()), and the JSON-mode bullet a few lines above was correctly updated to say "absent or stale". An agent relying on this recipe's description of non---json output wouldn't expect a warning when the entry is merely out of date rather than missing. Low severity — cosmetic/doc-only, no behavior is wrong.

Checked and found fine (not flagging):

  • The widened entry text's "sets a variable, changes or creates a directory, or redirects the call's output to a file" vs. "every other command is judged on its own" reads correctly as a backstop for the classifier, separate from the skill's standalone-command rule that's meant to prevent the chaining in the first place (per the design doc's own reasoning) — not a contradiction.
  • Duplicate-labelled-entry edge case (first entry stale, a later entry already matches GLOBAL_TRUST_ENTRY verbatim) would replace the first and leave a duplicate correct entry behind; harmless, and consistent with the documented "first labelled string only" behavior.
  • .changeset/refresh-global-trust-entry.md is patch, consistent with the package still being 0.13.0 (pre-1.0, so added/changed behavior stays patch per this repo's semver convention).
  • The skill body's 150-line cap is respected (counted it: 150 lines after the frontmatter, matching the installed-documentation.test.ts assertion and the PR description's claim).

No other correctness, security, or test-adequacy issues found in the diff.

@theCodeDrift

Copy link
Copy Markdown
Member Author

Re: @github-actions — "Claude finished @theCodeDrift's task in 2m 58s…"
#528 (comment)

Fixed the init.md doc drift in fd2df4f: the prose-mode line now says a warning prints for each missing or stale global trust entry. The duplicate-labelled-entry case is left as documented (first labelled string only).

— AI Coding Agent

The standalone-command rule and the present-entry fallback brought the body to exactly 150 lines. Raise the cap in skill-taskless and its test rather than compress guidance an agent acts on.
@theCodeDrift
theCodeDrift merged commit 6ccb612 into main Oct 17, 2026
8 checks passed
@theCodeDrift
theCodeDrift deleted the refresh-global-trust-entry branch October 17, 2026 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant