- Canal 1024 store:
npm i -g dsh1024uma vez, depoisdsh1024 plugin --profile web add dsh-permission-rules(conta para o ranking de instalações do deepseek1024.com).
Regras de permissão declarativas estilo Claude Code para o DeepSeek Harness.
Regras decidem o conhecido. Um modelo revisor decide o que não é.
English · 简体中文 · Español · Português · हिन्दी
dsh plugin --profile <name> add dsh-permission-rules📖 Base de conhecimento do ecossistema — dados medidos, não marketing: guia de desenvolvimento · dados de seleção · critérios de manutenção.
- canal git (último
main):dsh plugin --profile web add github:PerryLink/dsh-permission-rules— o scriptpreparecompila apenas com dependências de produção. - canal npm (versões publicadas):
dsh plugin --profile web add dsh-permission-rules. - canal tarball:
pnpm packneste repo, depoisdsh plugin --profile web add ./dsh-permission-rules-<version>.tgz. - desinstalar:
dsh plugin --profile web remove dsh-permission-rules.
Este plugin faz parte da família de plugins DSH (mais de 40, todos Apache-2.0). Se for útil, deixe uma estrela: não desbloqueia nada, mas ajuda a próxima pessoa a encontrá-lo.
English: part of a 95 plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.
Regras de permissão declarativas estilo Claude Code para o DeepSeek Harness.
Regras decidem o conhecido. Um modelo revisor decide o que não é.
Visão geral do fluxo: solicitação → política/revisão → veredito. Os exemplos abaixo usam a superfície real de comandos.
A mesma execução, animada.
| Surface | Status |
|---|---|
| Harness | DeepSeek Harness dsh-v0.2.1-alpha.1 (adaptado em 2026-09-22, cadeia completa de gates): a configuração do plugin é o contrato de settings ao vivo — cada campo é declarado .volatile(), o Loader entrega a apply uma referência viva por campo, e uma edição salva é confirmada nas referências em execução SEM remontar o plugin, com valores fora da faixa recusados pelo schema antes de qualquer escrita. Um host cujo Schemastery seja anterior a volatile() (antes de 3.18.3) ainda monta e executa este plugin — os campos apenas permanecem valores comuns e o formulário de configuração ao vivo fica indisponível — porque o marcador é aplicado por sondagem de capacidade, não por suposição. O Session.append nesta linha ainda não consegue estampar o marcador ignorable (seu terceiro argumento é o pacote surface-intent, e o campo do envelope só sobrevive para a leitura de logs armazenados), então toda a linha 0.2-alpha é pré-verificada como não marcada e a auditoria do log de sessão fica desativada por padrão — o append lê apenas sourceEventSeqs/surfaceOp e congela o envelope, portanto não há caminho de código capaz de estampar o marcador; as linhas anteriores 0.1.7-alpha (adaptada em 2026-09-22), 0.1.5-rc.2 (adaptada em 2026-09-09) e 0.1.3-alpha mantêm a mesma assinatura de append surface-only, e toda versão pré-lançamento 0.2 é classificada junto delas (uma versão ESTÁVEL 0.2.x fica a cargo da sondagem de append, então uma superfície de marcação restaurada é adotada sem um novo lançamento deste plugin). As migrações de log dessas linhas recusam eventos de plugin não classificados mesmo marcados: aplique strip nas linhas de auditoria v1 antes de um host 0.1.3-alpha abrir o log e nas v2 antes de um host 0.1.5-alpha migrá-lo (logs v3 nativos só precisam de repair). |
| Node | `^22.19.0 |
| Platforms | Todas (host + cliente web de settings) |
| Model | Qualquer (razões deny/ask aparecem pelos resultados de ferramenta) |
O dsh-permission-rules antepõe uma lista ordenada de regras allow / deny / ask a cada chamada de ferramenta na cascata tools/pre-execute — determinística, instantânea, auditável e escrita por você em YAML puro:
denybloqueia a chamada; areasonda regra vira o erro visível para o modelo.askusa a costura oficial de aprovação (monte odsh-auto-reviewpara um answerer de segundo modelo, ou um humano responde; sem nenhum, o harness falha fechado).allow(e sem correspondência) delega estritamente vianext()— os listeners posteriores nunca são curto-circuitados.
Cada acerto e cada passagem direta é registrada como um evento de sessão permissionRules/decision (somente log — nada extra é injetado no contexto do modelo).
- Correspondência rica — globs de nome de ferramenta (incl.
mcp__*), seletores de identidade de agente (main/subagent/preset:*), globs ou regexes de chave/valor de argumentos (com negação!patterne dimensão de chaveabsent), globs de caminho relativos ao workspace em qualquer profundidade de aninhamento, condições de hostwhen(variáveis de ambiente, plataforma), e decomposição de comandos de shell (argv: palavra de comando, tokens de argumento, assinatura de pipeline) para correspondência precisa por token. - Linha de base de alto risco integrada — um conjunto deny/ask embarcado (comandos destrutivos, escalada de privilégios, baixar-e-executar, caminhos sensíveis) habilitado por padrão e anexado após as regras de usuário (uma regra de usuário mais próxima pode sobrescrevê-lo); alterna com
builtin.enabled. - Arquivos de regras hierárquicos —
searchUpopcional mescla cada.dsh/rules.yamldo cwd da sessão até a raiz do sistema de arquivos, o mais próximo primeiro. - Implantação em dry-run —
enforce: falseaudita o que a política faria enquanto deixa cada chamada passar. - Recarga a quente — vigilância Chokidar com debounce; uma edição quebrada mantém as regras anteriores, nunca falha. Num host WSL, ou para um arquivo de regras sob
/mnt/<unidade>, a vigilância passa a polling porque os eventos nativos de mudança não são confiáveis ali. - Falha ruidosa — YAML inválido, ações/campos desconhecidos, globs/regexes ruins, padrões propensos a backtracking ou mais de
maxRulesregras falham a carga.
# <project>/.dsh/rules.yaml
rules:
- match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["**/secrets/**"] }
action: deny
reason: "No pushes from protected paths"
- match: { tools: [edit, write] }
action: ask
reason: "File writes need confirmation"- Dimensões de correspondência —
tools(globs, incl.mcp__*),agents(main/subagent/preset:<name>; identidade desconhecida nunca corresponde — falha fechado),params(globs ou regexes de chave/valor, negação!pattern, dimensão de chaveabsent),paths(globs relativos ao workspace extraídos a qualquer profundidade),when(globs/regexes de variáveisenv+ listaplatformfechada), enetwork(domains/ips/ports/schemes— globs, curingas, CIDR, faixas de porta). - Ações —
allow/deny/ask, avaliadas em ordem de arquivo, primeira correspondência vence. - Metadados de regra —
enabled: false(visível mas inerte),description,tags; campos desconhecidos falham a carga. - Schema — um JSON Schema é distribuído em docs/rules-format.schema.json (autocompletar de editor via
# yaml-language-server: $schema=...); o vocabulário completo e uma linha base de 5 regras vivem em docs/rules-format.en.md.
Uma política de rede em nível de processo estilo Codex: o tráfego de subprocessos de shell flui por um proxy HTTP/CONNECT local integrado, e cada conexão é decidida por regras de rede ordenadas ou por três modos mapeados sobre os presets oficiais do sandbox:
-
deny-all— o preset de sandbox somente leitura: bloquear todo o tráfego de saída. -
whitelist— o preset workspace-write: permitir destinos listados,unlisted: ask(oudeny) para o resto. -
allow-all— o preset danger-full-access: permitir tudo. -
auto(padrão) — segue o preset do sandbox; em hosts sem o serviço de política de sandbox resolve paraautoFallback(allow-all). -
Correspondência —
match.networkcomdomains/ips/ports/schemes(globs, curingas, CIDR, faixas de porta; portas YAML numéricas são aceitas). A extração de candidatos URL na rota quentetools/pre-executedispara sobre argumentos de ferramentas web e URLs embutidas em texto de comando bash/pwsh; destinos de loopback podem curto-circuitar regras conforme a políticaloopback. Literais IPv6 mapeados em IPv4 são normalizados para a forma IPv4 antes da comparação, e o proxy conecta nos endereços usados na decisão, sem uma segunda resolução DNS; uma conexão cuja adjudicação não resolveu nenhum endereço falha fechada (502) em vez de discar o nome. -
Encadeamento por proxy ascendente —
network.upstreamProxy(padrãooff) envia as conexões que este proxy permite por um proxy ascendente: o CONNECT pede um túnel a ele (CONNECT host:port) e as requisições HTTP simples são encaminhadas em forma absoluta. Um destino bloqueado nunca chega ao proxy ascendente — ele continua recebendo o 403 estruturado deste plugin. Dois casos nunca encadeiam, mesmo com um proxy ascendente configurado: um destino de loopback (um proxy fora deste host não consegue rotear o loopback dele) e qualquer decisão produzida por uma regra com escopoips(encadear entrega o nome do host ao proxy ascendente, então «a conexão chega a um endereço que as regras viram» — issue #21 — deixaria de valer exatamente onde as regras se importavam com o endereço; essas decisões continuam conectando direto no endereço adjudicado), além de um destino cujo esquema não tenha um proxy ascendente utilizável. O nome do host do próprio proxy ascendente é configuração do operador, não entrada do agente, e não é adjudicado por estas regras. Uma URL com credenciais nunca é emitida em claro: avisos,/rules networke o snapshot de settings mascaram a senha (http://user:***@host:port). Um proxy ascendente inalcançável, um timeout (10 s) ou uma resposta não 2xx resultam em 502 — não há, de propósito, queda silenciosa para conexão direta, para que uma má configuração continue visível. -
Auditoria — conexões negadas anexam
permissionRules/networkà sessão proprietária (a mesma porta adaptativaignorable), com contadores de bloqueio e intercepções recentes em/rules networke na página de settings. -
Diagnóstico — conexões bloqueadas trazem uma mensagem
[network: …]nomeando o destino bloqueado, o modo ou a regra que decidiu e a solução. -
Permitir pela página de settings — cada intercepção recente oferece uma ação Permitir. Ela grava UMA regra mínima
match: { network: { domains: [<host>] } }/action: allowno topo (índice 0) do arquivo de regras mais próximo que realmente julga aquela conexão: o arquivo de projeto do workspace ao qual o bloqueio foi atribuído (orulesFileabsoluto quando há um configurado) ou, para um bloqueio de host sem sessão, o arquivo que a cadeia do host resolve (rulesFileabsoluto →<processCwd>/<rulesFile>existente →fallbackPathconfigurado →<processCwd>/<rulesFile>, criado). Com vários workspaces carregados, a página oferece primeiro um seletor, porque qualquer cadeia de workspace carregada tem precedência sobre a cadeia do host. No índice 0 porque as regras são de primeira correspondência: acrescentada depois de umdenyexistente, a regra seria texto morto. Somentedomains, porque essa dimensão inclui subdomínios e independe de porta/esquema, então o host não volta a ser bloqueado na próxima porta; comentários e regras não tocadas sobrevivem, e o texto passa pela mesma porta de validação de uma edição manual. A mudança entra em vigor imediatamente — as cadeias de workspace em cache E a cadeia de host sem sessão são relidas, sem reinício e sem/rules reload— e a decisão é recalculada, então o aviso informa o resultado REAL e nunca afirma sucesso enquanto a conexão continua bloqueada. Recusa, sem tocar no arquivo, um workspace desconhecido, um destino fora das fontes de regras conhecidas, a linha de base integrada somente leitura e um arquivo que não consegue ler ou analisar; uma conexão já permitida não grava nada.network.allowHostAction: falseoculta o botão e faz o RPC recusar.
dsh plugin --profile web add github:PerryLink/dsh-permission-rules# 1. install the bundle into your profile
dsh plugin --profile web add github:PerryLink/dsh-permission-rules
# or from npm (published releases)
dsh plugin --profile web add dsh-permission-rules
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A4 'id: permission-rules'São os pontos de entrada reais; instale e chame um.
Comando
/rules test bash {"command":"git push origin main","cwd":"src/secrets/app"}Saída
"bash" matches rule 1 (deny): 禁止 push 到受保护路径
Observado em test/command.spec.ts:204-219 (assertions at :209-213); src/prose.ts:121
Entrada
/rules test bash {not json
Saída
Invalid JSON arguments "{not json": the arguments must parse as JSON.
Observado em plugins/dsh-permission-rules/src/prose.ts:123; plugins/dsh-permission-rules/src/runtime.ts:1266-1272; plugins/dsh-permission-rules/test/command.spec.ts:221-228
tools/pre-execute
Todos os parâmetros são campos Schemastery Config (alteráveis pelo cordis.yml). Uma sobrescrita direcionada por id substitui a linha inteira — reafirme cada chave de que precisa. Num host 0.1.7-alpha cada campo é declarado .volatile(), então TAMBÉM é editável no local pela página de Plugins: a edição é confirmada nas referências em execução sem remontar o plugin, o runtime lê o novo valor no uso seguinte, e uma mudança em network.proxyPort, proxyBind, injectEnv ou noProxy revincula o proxy local imediatamente. Os limites numéricos ficam no schema, e o editor de configuração resolve a configuração mesclada contra esse schema antes de persistir, então um valor fora da faixa é recusado no momento da escrita. Num host cujo Schemastery seja anterior a volatile() estes campos só mudam por cordis.yml.
| Key | Default | Meaning |
|---|---|---|
rulesFile |
.dsh/rules.yaml |
Local do arquivo de regras; relativo = resolvido contra o cwd da sessão, absoluto = global e validado na montagem |
fallbackPath |
(none) | Arquivo de regras usado quando a detecção por cwd não encontra nada; validado na montagem |
badFilePolicy |
fail |
Arquivo de regras ruim: fail faz a chamada pendente falhar ruidosamente; ignore-with-warning avisa e continua vazio |
maxRules |
256 |
Limite rígido de contagem de regras na cadeia fonte efetiva |
maxCachedWorkspaces |
512 |
Limite rígido de cargas de regras por workspace em cache (evicção LRU) |
patternMode |
glob |
Sabor de padrão params/paths/when.env: glob ou regex (nomes de ferramenta são sempre globs) |
watch |
true |
Vigilância Chokidar + recarga ao mudar |
watchStabilityThresholdMs |
200 |
Janela de debounce de recarga (ms) |
language |
en |
Idioma de saída de /rules: en, zh, es, pt, hi |
caseInsensitivePaths |
(win32) | Padrões paths e comparação de raiz do workspace ignoram maiúsculas ASCII; true no Windows |
audit |
all |
Granularidade de auditoria: all registra cada acerto E passagem; hits omite eventos de passagem |
searchUp |
false |
Percorrer diretórios pai do cwd e mesclar cada arquivo de regras encontrado, o mais próximo primeiro |
maxGlobStars |
2 |
Limite rígido de quantificadores */** não limitados por padrão glob |
enforce |
true |
false = modo dry-run: acertos deny/ask são registrados com marcador dryRun e cada chamada passa |
allowUnmarkedAudit |
false |
Hosts anteriores ao marcador descartam o marcador ignorable; o plugin desativa a auditoria de log com um aviso. Ponha true para reativar |
network.enabled |
true |
Interruptor mestre do proxy, da injeção de ambiente e dos padrões de modo de ferramenta web |
network.mode |
auto |
Modo de política: auto segue o preset do sandbox, ou deny-all / whitelist / allow-all |
network.autoFallback |
allow-all |
Modo usado quando auto não tem serviço de política de sandbox |
network.unlisted |
ask |
Manejo em modo whitelist de destinos sem regra coincidente: ask ou deny |
network.proxyBind |
127.0.0.1 |
Endereço de vínculo do proxy local (somente loopback) |
network.proxyPort |
0 |
Porta do proxy local; 0 escolhe uma porta efêmera livre |
network.proxyMaxRecent |
100 |
Limite de registros de bloqueio recentes para a página de settings |
network.loopback |
allow |
Destinos de loopback: allow (paridade Codex) ou policy |
network.injectEnv |
true |
Se variáveis de ambiente do proxy são injetadas para subprocessos |
network.noProxy |
clear |
Manejo de NO_PROXY em subprocessos: clear aplica a política ou preserve |
network.upstreamProxy |
off |
Proxy ascendente para as conexões que este plugin PERMITE: off conecta direto, inherit reutiliza os nomes de proxy do ambiente de lançamento, ou uma URL de proxy http(s):// explícita |
network.allowHostAction |
true |
Ação «permitir este host» por bloqueio da página de settings: false oculta o botão Permitir e faz o RPC permissionRules/allowHost recusar (o editor de regras não é afetado) |
builtin.enabled |
true |
Linha de base de alto risco integrada: false desabilita por completo o conjunto deny/ask embarcado |
builtin.path |
(embarcado) | Arquivo de linha de base de substituição (absoluto, ou relativo a process.cwd()); validado ao montar |
| Surface | Kind | Notes |
|---|---|---|
tools/pre-execute |
listener | Regras allow/deny/ask de primeira correspondência + extração de candidatos URL de rede |
/rules |
command | list · reload · decisions [n] · test <tool> <json> |
permissionRules/decision |
event | Auditoria somente de log para cada acerto e passagem |
permissionRules/network |
event | Auditoria da camada de proxy para conexões bloqueadas |
| HTTP/CONNECT proxy | service | Proxy local integrado que governa o tráfego de subprocessos de shell |
| settings page | client | Editor de modo de rede, editor de regras, contadores de bloqueio, intercepções recentes com uma ação de permissão por bloqueio |
/rules list the active rules, their source files, and any last-reload error
/rules list explicit alias for the bare listing
/rules reload re-read the rule-file chain for this workspace
/rules decisions [n] show the last n permission decisions of this session (default 10)
/rules test <tool> <json> dry-evaluate the rules against a hypothetical call
/rules test também aceita bandeiras iniciais: --cwd <dir>, --env KEY=VALUE (repetível), --agent <selector> (repetível) e --platform <name>. Em cadeias multi-arquivo (ex.: searchUp), cada linha de regra listada é atribuída ao seu próprio arquivo fonte.
- Permissions: o manifesto de workshop declara
files:read,files:watch,files:write,session:appendenetwork:outbound. Decisõesaskusam a costura oficial de aprovação — nada é reimplementado ou contornado. - Data: arquivos de regras são lidos do disco; nenhum dado de regra é escrito. Sem chamadas de modelo, sem subagentes revisores.
- Session log:
permissionRules/decisionnunca é injetado no contexto do modelo e é anexado com o marcadorignorable: truedo envelope, de modo que qualquer build do harness carrega o log.
- Política, não kernel. Candidatos
pathsvêm apenas de um conjunto documentado de chaves de argumento (a qualquer profundidade, com limite), e apenas caminhos relativos ao workspace correspondem. - Aqui não há revisor. O plugin nunca gera subagentes nem chama modelos — produzir uma decisão
aské o fim do seu trabalho. - Sem mudanças de sandbox. A política de sandbox em nível de SO pertence à costura do sandbox, não a este plugin.
- Rejeição ruidosa de má configuração. Campos YAML desconhecidos, ações desconhecidas e padrões ruins são rejeitados na carga.
- Limites de backtracking. Padrões glob são limitados a
maxGlobStarsexpansões de estrela não limitadas; padrões regex rejeitam quantificadores aninhados não limitados e alternâncias literais sobrepostas quantificadas. - Discagem à prova de falhas. Encaminhamentos HTTP simples e túneis CONNECT conectam apenas a endereços adjudicados; um allow cuja adjudicação não resolveu nenhum endereço falha fechado com 502 em vez de discar o nome (issue #23).
- Marcador de auditoria em hosts anteriores ao marcador ou que rejeitam eventos.
permissionRules/decisioné anexado comignorable: true; hosts cujoSession.appendé anterior ao marcador (as linhas0.1.0-rc.1–rc.7e0.1.1-rc.1–rc.7) o descartam silenciosamente, a linha0.1.2-rctraz a superfície alpha.5 (nenhuma opção de append escreve o marcador), a linha0.1.2-alpharejeita eventos de plugin na leitura mesmo marcados, e as linhas0.1.3-alphae0.1.5-alphamantêm a mesma assinatura de append surface-only (verificado nos pacotes publicados0.1.3-alpha.1/0.1.5-alpha.1) — o runtime pré-verifica todas elas antes do primeiro append e desativa a auditoria de log com um aviso único. A migração entre gerações também rejeita linhas de auditoria marcadas: a porta v1→v2 da0.1.3-alpharejeita eventos v1 desconhecidos, e a porta v2→v3 da0.1.5-alpharejeita todo evento não classificado (seu inventário é congelado ao vocabulário v2 publicado), então apliquestripnas linhas v1 antes de um host 0.1.3 abrir o log e nas v2 antes de atualizar para um host 0.1.5. Logs v3 nativos aceitam linhas de plugin marcadas, então só precisam derepair. DefinaallowUnmarkedAudit: truepara reativar; repare logs já escritos comscripts/repair-session-logs.mjs(seu modostripremove linhas de auditoria onde o marcador não ajuda). - Candidatos de caminho são heurísticos. Somente as chaves de argumento documentadas alimentam a correspondência de caminho, e a correspondência relativa ao workspace é insensível a maiúsculas ASCII apenas com
caseInsensitivePathsativado. - Globs são um subconjunto conservador. Sem expansão de chaves — escreva dois padrões, ou use o modo regex.
- A guarda de backtracking de regex é estrutural, não exaustiva. Prefira o modo glob para arquivos não confiáveis.
- As requisições de saída do próprio host não passam por este proxy. O ambiente de proxy injetado cobre os subprocessos de shell derivados — que é para isso que a injeção serve — e qualquer consumidor que leia os nomes de proxy no momento da requisição. Não cobre o tráfego baseado em
fetchdo próprio processo do host: o launcher instala o dispatcher global do undici a partir do ambiente de lançamento antes de o primeiro plugin ser montado, esse dispatcher roteia pela sua política e não pelo ambiente, e o Node amostra o ambiente de proxy na inicialização, então um plugin montado depois não consegue redirecioná-lo. Consequências: os endpoints do provedor não precisam de uma regra allow, enetwork.injectEnv: falsenão tira o processo do host de nada. Medido em 2026-09-10 no Node 22; reproduza comscripts/host-egress-probe.mjs. - O encadeamento cobre apenas o que chega a este proxy. Em
dsh-v0.1.7-alpha.1e posteriores, a própria política de proxy de lançamento do harness e sua camada de ambiente para subprocessos podem ter precedência sobre os nomes de proxy que este plugin injeta, entãonetwork.upstreamProxydescreve o que acontece com as conexões que este proxy trata — não é uma afirmação sobre todos os caminhos de saída do processo do host.
- O
dsh-permission-rulesproduzask; odsh-auto-reviewresponde na cascataapproval/requestcom um veredito de segundo modelo somente leitura (ou delega a humanos). Monte ambos para o laço completo fechado. - Testado em integração:
permissionRules/decision→approval/asked→autoReview/verdict→approval/decided, com o revisor substituído por um mock roteirizado. - A política de aprovação
nevere toda garantia de falha fechada do harness oficial permanecem intactas.
Logs de sessão escritos antes de o marcador ignorable existir podem ser recusados por builds mais novas do harness (SessionFormatUnsupportedError). O scripts/repair-session-logs.mjs distribuído reescreve apenas as linhas de auditoria alvo para carregar ignorable: true, preservando quadros, com backups:
node scripts/repair-session-logs.mjs scan [--home DIR] # relata linhas estranhas, não muda nada
node scripts/repair-session-logs.mjs repair [--home DIR] [--dry-run]
node scripts/repair-session-logs.mjs strip [--home DIR] [--dry-run]--home por padrão é $DSH_HOME/sessions (ou ~/.dsh/sessions). Ele descobre cada log pelo nome canônico da geração — session.jsonl, session.v2.jsonl, session.v3.jsonl, cada um opcionalmente comprimido em .zstd — então escolha o modo pela geração:
- v3 (
session.v3.jsonl, escrito nativamente pela linha0.1.5-alpha) — o caminho de leitura aceita linhas de plugin marcadas, entãorepairbasta. - v2 (
session.v2.jsonl, escrito pela linha0.1.3-alpha) —repairo abre no host que o escreveu, mas a migração v2→v3 da0.1.5-alpharejeita todo evento não classificado mesmo marcado: executestripnos logs v2 antes de atualizar para um host0.1.5-alpha. - v1 (
session.jsonl) — a migração v1→v2 da0.1.3-alpharejeita eventos v1 desconhecidos mesmo marcados: executestripantes de um host 0.1.3 ou posterior abrir o log pela primeira vez.
pnpm install # node ^22.19 || >=24
pnpm run typecheck # tsc, src + tests
pnpm run lint # eslint, src + tests + scripts
pnpm test # vitest: 24 spec files
pnpm run test:coverage # coverage gate (90/80/90/90)
pnpm run build # tsc declarations + tsdown bundles (lib/)
pnpm run pack:check # build + pack (the published artifact)
node scripts/check-readme-sync.mjs # five-language README sync gate (also in CI)Consulte VERIFICATION.md para o registro de verificação end-to-end sem cabeça.
Verificado contra DSH 0.2.0-rc.2 (o runtime para o qual este README é publicado) e o conjunto de plugins com mais estrelas pesquisado em 2026-10-05.
Este plugin não interfere em outros plugins, incluindo os de mais estrelas:
- Sem colisão de nome de ferramenta. Todas as ferramentas têm namespace; nenhuma ocupa um nome puro já pertencente a uma ferramenta embutida ou a outro plugin.
- Sem colisão de chave de serviço. Fornece apenas
permissionRules,permissionRulesRuntime; essa chave não é uma costura embutida nem é fornecida por nenhum plugin de mais estrelas. - Sem colisão de slot. Não registra nenhuma chave de slot de cliente, então não disputa um assento
shadows-shipped-ui. - Sem colisão de rota HTTP. Não registra nenhum prefixo
webServer. - Sem colisão na camada de patch. O patch do bundle apenas faz
insertda própria linha; nunca sobrescreve oconfigde uma linha embutida. - Sem mutação global. Não altera protótipos, não reescreve
process.envnem substitui o dispatcher global de fetch.
Listeners de eventos compartilhados não interferem por construção. Observa os eventos sensíveis à ordem tools/post-execute, tools/pre-execute com ctx.on() — o registro de difusão do Cordis, onde cada listener executa e nenhum pode privar outro do turno. Todos os listeners aqui delegam via next(), então a cadeia nunca é curto-circuitada:
tools/post-execute— also used bycc-safety-net(1576★).tools/pre-execute— also used bycc-safety-net(1576★).
Evidência estática: dsh-plugin-doctor K10–K13 retornam pass em todas as verificações deste repositório.
dsh, dsh-plugin, deepseek-harness, permission, policy, allow-deny-ask, approval, safety, network, network-policy, proxy
- @PerryLink — criador e mantenedor: vocabulário e avaliação de regras, runtime, vigilância HMR, auditoria de log de sessão, política de rede + proxy, e a documentação em cinco idiomas.
- @22xuan — o relatório detalhado sobre hosts rc.6 descartando silenciosamente o marcador
ignorabledo evento de auditoria (#2) e a discussão do harness upstream; a detecção de capacidade de host em runtime v0.4.1 e a correção de documentação se derivaram diretamente dessa análise. - @sjh9714 — propôs o corpus compartilhado de vetores de teste de sintaxe de regras (#4, #5), incluído na v0.5.1 como
docs/rule-test-vectors/, e contribuiu com os casos-limite de decomposição AST na discussão de design. - @weipeng1999 — a proposta de decomposição de comandos baseada em AST (#8) por trás da discussão de design.
- @alexchenzl — a solicitação de inclusão no DSH Directory (#7).
- @zl190 — relatou e verificou a lacuna de compatibilidade do harness
0.1.0-rc.7(PR #9). - @cuohua — relatou que a linha
0.1.1-rcainda descarta o marcadorignorableembora a verificação de versão cobrisse apenas0.1.0(#11); a verificação ampliada veio diretamente dessa análise.
Este projeto faz parte da família de plugins do DeepSeek Harness da PerryLink. O registro fica recolhido abaixo para que cada README mantenha uma primeira tela curta; expanda para ver cada linha e seu status.
Expandir todos os plugins
Apache License 2.0 © 2026 dsh-permission-rules contributors
Todos os plugins PerryLink podem ser explorados no mercado integrado do DSH Desktop: Market → Sources → add source → colar https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → selecionar. A instalação continua passando pela verificação de identidade npm do mercado e pela sua confirmação.