chore: sync private v5.5.0 (8bb0ffd) - #47
Merged
Merged
Conversation
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.
Summary
v5.5.0.sync/v5.5.0-8bb0ffd.Release notes
Added
.cursor/skills/domain/llm-security-ops/(SKILL.md +owasp-llm-map.md,local-lab-ops.md,mitigation-patterns.md): OWASP Top 10 for LLM Applications 2025 detect/mitigate/review checklists plus local LLM lab ops (Docker Compose + Ollama), distilled from the external Urutau-LLM-Lab curriculum. Project-owned and one-way: not a registry member, not a pack member, no L0 command, not consumer-installable — it layers on thesecurity-revieweragent andcybersecpack without replacing classic AppSec checklists. Educational/defensive only (no exploit payloads or flags in-tree); the lab itself stays external and unvendored. ADR2026-08-17_urutau-llm-lab-external-curriculum-domain-skill.md; first member of the.cursor/skills/domain/scaffold (ADR 2026-08-02).--force-rootand the start-from-zero path for the first time:docs/getting-started.mdgains Project root guard (which shapes are refused, warn-vs-refuse by interactivity) and Starting from an empty folder (git initrecommended,--force-root, or the interactiveProceed anyway?yes).install.mdmirrors both. Installing without Git stays supported -/agent-kit-onboardstill owns the Git pillar and the CLI never runsgit initfor you..cursor/context/audit-wait/<slug>.jsonisdeadlinevs wall clock, notstatus: "armed". Any arm or poll expires that slug's own dead file on contact (status->timeout,remainingBudgetSeconds->0, witharmEpoch,deadline,backend,implementerModel,reviewerModel, and anycloudAgentId/cloudRunIdpreserved), so a stale arm is never resumed as live leftover budget. New opt-in sweep--gc-wait-state(orAGENT_KIT_AUDIT_GC_WAIT_STATE=1) walks every wait-state file, expires each dead armed one, skips live and already-terminal files with one line per decision, and with no plan argument sweeps and exits0without starting an audit;--dry-runpreviews. No new status outside the ADR enum (armed|ready|timeout|soft-fail). Tests.cursor/scripts/plan-external-review-atomic-wait.test.mjs.status: "timeout"/"soft-fail", or"armed"pastdeadline) and a genuine post-hocplan-monitor-<slug>.mdexists on disk,/run-planand/run-plan-alloffer an owed-close HITL:Adopt existing monitor(routes into/plan-review-triage <path>; the durable triage heading records reviewed-by-adoption) orAck owed without review(closes as acked, recorded unreviewed). The earlier exit3stays3, the wait-statestatusis never rewritten toready, and a duplicate re-arm against already-merged work is no longer the only sanctioned route.Not nowleaves the row owed.externalPlanReview.preflight) also refuses or warns on unsatisfiable config:enabled: truewithbackendpinned"claude"in the Claude CLI lane can only end owed (audits are a non-goal there, and a pinned Claude reviewer against a Claude implementer is an honest same-model skip), andmidBatchAudits: truemultiplies it across a queue.warnsurfaces the combination once with the outs (backend: "auto","cursor","cloud");blockdoes not start the run or the queue./run-plan-allchecks before the confirm Ask. A growing owed pile is no longer the only signal.agent-kit-audit-*sessions across four workspace tokens (13/10/2/1) on one 16 GB host while every token stayed underAGENT_KIT_AUDIT_SESSION_CAP=20— the cap is per token, the exhausted resource is the host. Ceiling: the launcher now also counts detached sessions across the wholeagent-kit-audit-namespace (foreign tokens and legacy unscoped names included) and refuses to spawn atAGENT_KIT_AUDIT_SESSION_HOST_CAP(default 24: at or above the per-token cap so it cannot shadow it, below the observed 26-session collapse;0disables). The refusal reuses the existing soft-fail shape (no new exit codes) and prints a per-token breakdown stating that the workspace-scoped dispose command only reaps this workspace's share. Attribution is unchanged: reap and dispose stay owned-token-only, and the--dry-runaudit-sessions:owned line is byte-identical, with a newaudit-sessions-host:line beside it. Lifetime: the detached tmux/screen spawn is now self-terminating at spawn — wrapped withtimeout/gtimeoutwhen available, else a watchdog subshell signaling only the session's own process group — afterAGENT_KIT_AUDIT_SESSION_MAX_AGEseconds (default 3600;0disables), so a forgotten session never depends on a later launcher run to die (the opt-inAGENT_KIT_AUDIT_REAPsweep stays a separate mechanism). Attached and foreign-token sessions are never killed; emulator/Terminal channels stay advisory; the 60s progress gate remains a launch honesty check, not a lifetime. Visibility: the sessionStart hook emits one fail-open section with the host-wide detached count and oldest age (only when count >= 1; silent on zero/missing tool/error, 2s timeouts), and Mission Control exposessystem.detachedAuditSessions({count, oldestAgeSeconds}|null) with a conditional note in the Processes section. Dogfoodcursor_audit_session_cap_host_scope_2026_08_14.md; ADR2026-07-30_audits-pty-progress-gate-zombie-policy.mdamended 2026-08-17.guard promptdetects hyphenated vendorsk-keys (sk-ant-api03-…,sk-proj-…) via a newsk-hyphenated-vendorpattern.openai-skis/\bsk-[A-Za-z0-9]{20,}\b/and its body class excludes-, so those keys returnedhits: []— indistinguishable from a clean prompt, with the fail-open prompt hook as the only net.maskSecretExcerptlearned the hyphen in the same change, so the new detection cannot put raw key material intoSecretHit.excerpt. Fail-open posture is unchanged. Memoryerrors/2026-08-14_guard-secrets-scope-vs-claims.md.install --claude(default install output unchanged without the flag):.claude/commands/<name>.mdthin pointer adapters for every installed.cursor/commands/*.md(no command prose copied, overlay-tracked so hand edits survive a re-run), and a SessionStart hook merged idempotently into.claude/settings.jsonso the same session context Cursor gets fromsessionStartnow auto-loads in Claude Code too.agent-kit hook session-startgained--format claude(plain stdout, live-docs-verified as the shape Claude Code's SessionStart hooks actually consume — no JSON wrapper, nonode -eunwrapper needed in consumer settings);--format cursorstays the byte-identical default. An existing.claude/settings.jsonthat fails to parse is never touched —installprints the hook entry to paste in by hand instead. ADR2026-08-13_claude-cli-kit-load-bootstrap.mdamended 2026-08-21 (reverses its own discarded SessionStart-hook alternative; the mechanism was always sanctioned by2026-07-29_cli-invariants-thin-hook-adapters.md, only the Claude Code surface was closed). Dogfoodcursor_claude_code_consumer_adapters_prototype_2026_08_16.md.agent-kit doctorreports an environment pillar (bin-on-PATH, npm global prefix writability, Node version, shell profile) via a newenvfield in--jsonoutput (env.binOnPath,env.npmPrefixWritable+env.npmPrefixdetail,env.nodeVersionOk+env.nodeVersion,env.shellProfile+env.shell) and a human "environment:" summary section. Read-only diagnostics, no writes.agent-kit setup-global: self-heals a root-owned npm global prefix (relocates to~/.npm-global, fixesPATHvia the detected shell profile with an idempotent marker comment, reinstalls globally, then verifies), with per-step confirmation,--dry-run, and a safe non-interactive fallback (prints manual copy-paste steps, mutates nothing). Neversudo/chown. Invoke vianpx @dadado/agent-kit-cli setup-global(works before a global install) or bareagent-kit setup-globalafter one.Changed
install/init's post-install "what now" line is now environment-aware:printInstallEpilogue()prints a 3-option guided block (keep using npx / runsetup-global/ manual steps) when a bareagent-kitisn't onPATHyet, instead of the old static npx-ephemeral hint. When the bin is already onPATH, it prints one short positive line instead.classifyInstallError(packages/cli/src/utils/terminal.ts) distinguishes a root-owned npm global-prefixEACCES(newnpm-global-eacceskind) from the genericepermkind, pointing recovery atnpx @dadado/agent-kit-cli setup-globalplus the manual one-liner instead of the generic npm-cache-ownership hint.Fixed
validateProjectRootno longer treats any directory with.gitas a project root. A root that has.gitand two or more immediate child directories that are themselves repositories is a parent-of-repos: refused in non-interactive mode, warned with a default-noProceed anyway?prompt interactively. Previouslynpx @dadado/agent-kit-cli installone level above the intended project wrote L0 into the wrong grain, silently under--yes/CI. The scan is one level deep, skips dot-directories andnode_modules, stops at the threshold, and is capped at 200 entries. Threshold is 2 because a single nested repo is the normal vendored/submodule shape; a child-directory count alone would false-positive on monorepos. A root that already has.cursor/agent-kit.jsonis never re-flagged.--force-rootstill bypasses, andupdategets the same behaviour.agent-kit initruns the project-root guard. It is a compat wrapper overperformInstall, which writes L0, but it never calledconfirmProjectRoot- soinitin a blank no-git folder or a parent-of-repos root wrote the tree with no confirmation, bypassing the guard entirely. It now confirms the same wayinstalldoes and accepts--yes/--force-root.recoveryblock next to the shortreason, andinstall/update/initprint it on a hard refusal:git inithere (recommended),--force-root, or yes at the interactive prompt. The empty-folder refusal used to name only--force-root, which no consumer doc mentioned.agent-kitis onPATH.npx @dadado/agent-kit-cli installis ephemeral and never linksbin.agent-kit, sodocs/getting-started.mdnow leads with the two honest invocation forms (npx @dadado/agent-kit-cli <subcommand>, ornpm i -g @dadado/agent-kit-clithen bareagent-kit) and its command table lists subcommands rather than a PATH binary;install.mdand the README Mission Control fences follow.installandinitshare onenextStepAfterInstall/ONGOING_CLI_INVOCATIONpair, pinned by tests.npxstays ephemeral - only the copy changed.guard shell --helpand theshell-guard.tsheader call it a git-workflow / protected-branch deny-list instead of "the destructive deny-list":SHELL_DENY_RULESis five git-scoped rules andrm -rf /,chmod -R 777 /,dd …are allowed by design (ADR2026-07-29_cli-invariants-thin-hook-adapters.md) — the claim was renamed, no rule was added andALLOW_MAIN_PUSHis untouched.SECRET_PATTERNSstates its relation to pre-commitcheck-secretsas one-way (the prompt scan is a strict superset; the hook greps the singlejson-secret-kvexpression under*.json|*.js|*.ts|*.env, so.md/.yaml/.sh/ dotfiles are scanned by neither lane) instead of claiming alignment. Each sentence is now pinned by a test against the rule set, the pattern ids, and the hook file, so prose cannot drift.Source
8bb0ffdsync/v5.5.0-8bb0ffd