# Lunheng (lunheng-article-pipeline) — pipeline multiagente para textos longos

> 版本：v19.27.15（DSH bundle：package.json + cordis.patch.yml + lib/index.js）

> 🌐 [English](README.md) ｜ [中文](README-zh.md) ｜ [Español](README-es.md) ｜ **Português**（este arquivo）｜ [हिन्दी](README-hi.md)

> Um bundle do DeepSeek Harness (DSH) que registra **duas skills de agente sob demanda**: `lunheng-article-pipeline` (a pipeline principal de 9 papéis) e `lunheng-commands` (um invólucro fino que expõe 13 comandos de barra `/lunheng-*`: draft / resume / cite / audit / journal / ppt / history / rollback / status / stats / gate / abort / help; **sem papel novo e sem item novo do portão M**; ver `skills/lunheng-commands/SKILL.md`). A skill principal transforma a produção de textos longos — artigos acadêmicos, análise setorial, comentário econômico e artigos extensos — em uma **pipeline de 9 papéis com participação humana**.

## What this is

Lunheng é uma pipeline de escrita, não um gerador de texto. Divide a produção de um texto longo em 9 papéis independentes (T1–T9) ao longo de 6 fases, orquestrados com chamadas `subagent` do DSH, e entrega um resultado com base probatória, revisão de contra-argumentos, auditoria independente e pontos de controle humanos.

Os nove papéis são independentes e insubstituíveis: T1 busca bibliográfica, T2 busca de dados, T3 busca de casos, T4 análise, T5 redação, T6 companheiro crítico, T7 auditoria, T8 verificação final (executada pelo próprio coordenador), T9 revisão por pares.

## When to use it

- Você precisa de um texto extenso (mais de 2000 caracteres) que resista a escrutínio e pode esperar várias horas (sem faixa horária; veja `skills/lunheng-article-pipeline/SKILL.md` §边界).
- O tema envolve fatos, números ou múltiplos pontos de vista, exigindo base probatória em vez de opinião apenas.
- Você quer pontos de controle humanos: confirmar o esboço antes de redigir e revisar o rascunho final.

## When not to use it

Lunheng coleta **evidência publicada** e integra a evidência que você fornece. Não consegue produzir o seguinte sozinha; forneça o material primeiro ou use outra ferramenta:

- **Coleta de dados em primeira mão** — experimentos, questionários, entrevistas, trabalho de campo.
- **Análise estatística** — pode citar resultados, mas não executa SPSS/R/Python.
- **Coleta de dados brutos para gráficos** — renderiza visualizações; scraping, OCR e transcrição exigem ferramentas dedicadas.
- **Imagens ou vídeo originais** — o DSH não inclui geração de imagens; capas usam SVG local ou arquivos fornecidos.
- **Execução de código** — a pipeline executa apenas scripts autorizados; qualquer outra coisa exige sua aprovação explícita.

Regra prática: pergunte se a evidência já está **publicada**. Se estiver, Lunheng a coleta. Se não, forneça-a primeiro.

## What you get

| Item | Conteúdo |
|---|---|
| Fichas bibliográficas `[Lxx]` | Fontes publicadas com grau de confiança A/B/C e lista de precursores |
| Fichas de dados `[Dxx]` | Números com fonte, ano, vigência, nível de confiança e números conflitantes lado a lado |
| Fichas de casos `[Cxx]` | Estrutura do evento (quem/quando/o quê/o relato de cada parte), ou marcador explícito `[C-空]` |
| Esboço de análise | Fio argumentativo, mapeamento afirmação-evidência, plano de contra-argumentos, evidência portante |
| Rascunhos | Versões sucessivas com limpeza de vestígios de IA, cada uma de um redator independente |
| Relatórios | Relatório crítico (C1–C7), auditoria (G0–G14), revisão por pares (6 dimensões + periódicos) |
| Entregáveis finais | `final/定稿.md`, figuras, pacote probatório, notas de entrega, relatório do portão M |
| Integração com o DSH (instalação como bundle) | Quatro ferramentas **somente leitura**: `lunheng_m_gate` (pré-checagem mecânica do portão M), `lunheng_char_count` (contagem de caracteres chineses), `lunheng_handoff_check` (verificação de forma / versão / pares / agents-log do relatório de handoff) e `lunheng_ethics_sanitize` (desidentificação ética: mascara CPF/documentos, telefones, e-mails, cartões bancários, nomes de pessoas e topônimos em transcrições de entrevistas e notas de campo; devolve o texto mascarado para que quem chama decida onde gravá-lo; v18.60.1); se a sua sessão não as expõe, chame os mesmos scripts com `pwsh` como antes (mesma fonte de verdade). Comandos humanos `/lunheng-status` (lê `run/<projeto>/status.md`) e `/lunheng-stats` (painel de telemetria entre projetos; lança `scripts/lunheng-stats.mjs` com `--json` como único argumento em lista branca); nenhum gera mensagens de modelo. **Proteção de escrita dos arquivos de mecanismo**: um guard global recusa chamadas de ferramentas do tipo `write`/`edit` dirigidas ao pacote da skill, de modo que uma sessão não pode reescrever em silêncio as regras da própria pipeline. Limite declarado sem rodeios: o guard só vê **chamadas de ferramentas**; `pwsh` e qualquer subprocesso **não passam por este portão**; a exceção do proprietário é `LUNHENG_ALLOW_MECH_EDIT=1` (ou `config: { allowMechanismEdit: true }`). O **Config** do plugin (chave de implantação, na linha deste plugin do seu perfil) cobre `quiet`, `allowMechanismEdit`, `scriptTimeoutMs`, `scriptMaxOutputBytes`, `handoffLevel`, `hookRewriteContent`, `hookMaxBlockChars` e `hookMaxTotalChars`, `ethicsHook` e `panel` (v18.90.0; **ativado por padrão desde v18.93.0** — painel de execução, superfície HTTP **somente leitura** (prefixo próprio); para desativar use `LUNHENG_PANEL=0` ou `panel: false`, veja `SECURITY.md`) (v18.80.0: interruptor mestre do listener H2 de desidentificação ética, **ativado** por padrão; desative em fluxos puramente de código/documentação, onde as correspondências de nomes de pessoa são mensuráveis como todas de baixa confiança e só acrescentam ruído) — os dois primeiros e `panel` equivalem às variáveis `LUNHENG_QUIET` / `LUNHENG_ALLOW_MECH_EDIT` / `LUNHENG_PANEL`, enquanto `scriptTimeoutMs` / `scriptMaxOutputBytes` / `handoffLevel` / `hookRewriteContent` / `hookMaxBlockChars` / `hookMaxTotalChars` / `ethicsHook` são **somente Config (sem variável de ambiente)**; os dez são revisáveis com o perfil; uma **config inválida falha ruidosamente no carregamento** em vez de voltar em silêncio aos padrões. |

## Pipeline overview

```text
Fase 0  Tema          Confirmar tema, extensão, formato de citação; consentimento de serviços externos
Fase 1  Busca         T1 bibliografia ∥ T2 dados ∥ T3 casos (paralelo real e independente)
Fase 1.5 Lacuna    T1 nova busca direcionada (opcional; reverificação de [Dxx] + argumentos de lacuna, rótulos Permanent Gap)
Portão T2.5           Entradas de dados ≥ requisito do briefing; níveis de confiança completos
Fase 2  Análise       T4 analista → esboço de análise
Fase 2.5 Esboço       Revisão humana (no circuito)
Fase 3  Redação       T5 redator → rascunho v1
Fase 3.5 Perspectiva  O humano fornece contexto em primeira mão (no circuito) → rascunho v2
Fase 3.6 Crítica      T6 companheiro crítico → relatório C1–C7
Fase 4  Auditoria     T7 auditor → relatório G0–G14 e lista de revisão
Fase 4.2 Revisão      Redator + notas de revisão (≤2 rodadas, redator independente)
Fase 4.5 Figuras       Geração de figuras (SVG) antes do portão
Fase 4.6 Portão G14    Portão G14 de vestígios de IA (em série; congela o texto)
Fase 4.7 Revisão       T9 revisão por pares
Portão T7.5           Auditoria mais recente + lista P0/P1 + portão M exit 0 + isolamento
Fase 5  Verificação   T8 (executada pelo coordenador) → texto final, pacote probatório, notas de entrega
```

**Base probatória triangular** (`[L]` + `[D]` + `[C]`) — toda afirmação deve mapear para bibliografia, dados e, para afirmações sobre eventos, casos. **Auditoria independente** — quem audita nunca edita. **Quatro pontos humanos** — fases 0, 2.5, 3.5 e 5.

## Repository layout

```text
lunheng-article-pipeline/                 # o pacote é o repositório
├── package.json              # declara main (lib/index.js) + dsh.bundle.patch
├── cordis.patch.yml          # camada bundle: linha de autorregistro + 3 ferramentas subagent por nível (só são montadas se definir LUNHENG_*)
├── lib/index.js              # entrada do plugin: skill + ferramentas somente leitura + guard de escrita + /lunheng-status
├── skills/lunheng-article-pipeline/       # o corpo da skill (um diretório)
│   ├── SKILL.md              # entrada da skill (papéis, portões, limites de execução)
│   ├── AGENTS.md             # manual do operador
│   ├── QUICKSTART.md         # início em cinco minutos
│   ├── README.md             # readme da skill (chinês)
│   ├── references/           # 9 fichas de papel, modelos, algoritmos de portão, base de periódicos
│   └── scripts/              # scripts .mjs de verificação sem dependências (contagem: ver a linha de lista branca da skill)
├── skills/lunheng-commands/   # skill companheira: 13 comandos de barra /lunheng-* (draft / resume / cite / audit / journal / ppt / history / rollback / status / stats / gate / abort / help)
│   ├── SKILL.md              # entrada de comandos (lista de comandos, modelo de despacho)
│   ├── README.md             # readme no nível de comandos
│   ├── scripts/              # manipuladores de comandos (p. ex. lunheng-stats.mjs)
│   └── tests/                # testes no nível de comando (não rodam sozinhos; escopo manual do npm test)
├── scripts/                  # portões do repositório: superfície de empacotamento + higiene + fumaça do pacote
├── tests/                    # suítes node --test (scripts + fumaça da entrada)
├── docs/                     # instalação, uso, arquitetura, faq, solução de problemas
├── examples/preset/          # notas de níveis de modelo e guia de instalação
├── README.md                 # fonte em inglês
├── README-zh.md README-es.md README-pt.md README-hi.md
├── SECURITY.md CHANGELOG.md CONTRIBUTING.md LICENSE
```

A entrada do plugin registra `skills/lunheng-article-pipeline/SKILL.md` como skill com `resourceBase` apontando para esse diretório, então `references/**` e `scripts/**` resolvem-se relativos a ele a partir de qualquer diretório de trabalho.

A camada patch faz duas coisas: **insere uma linha para este pacote** (`- id: lunheng-article-pipeline` / `name: lunheng-article-pipeline`) — é essa linha que faz o loader importar `lib/index.js`, que é o que registra a skill — e insere as três ferramentas subagent por nível, que **não são montadas por padrão** (defina qualquer `LUNHENG_{RETRIEVAL,STRONG,AUDIT}_{PROVIDER,MODEL}` ou `LUNHENG_TIERING=on` para montá-las; `off` para forçar que não sejam montadas). **Essa linha é estrutural**: sem ela a entrada nunca é importada e a skill não aparece (defeito da v18.0.0, corrigido na 18.0.1; vigiado por `tests/bundle-contract.test.mjs`).

### Documentation

| Arquivo | Conteúdo |
|---|---|
| `docs/installation.md` | Instalação e verificação |
| `docs/usage.md` | Fluxo de uso (fases e estrutura de artefatos) |
| `docs/architecture.md` | Arquitetura (9 papéis, evidência triangular, auditoria G0–G14, M-gate) |
| `docs/introduction.md` | Introdução do plugin |
| `docs/faq.md` | Perguntas frequentes |
| `docs/troubleshooting.md` | Resolução de problemas de instalação/verificação (sintoma → causa → correção) |
| `SECURITY.md` | Política de segurança e limite de confiança |
| `CHANGELOG.md` | Histórico de versões |
| `CONTRIBUTING.md` | Guia de manutenção e publicação |

### Publishing (maintainers)

As versões são publicadas **apenas por tag**; `npm publish` local é proibido (contorna os portões de CI e a proveniência OIDC, e uma versão npm nunca pode ser sobrescrita).

```sh
git tag v19.27.15 && git push origin v19.27.15   # uma tag por push (GitHub: >3 tags em um push não dispara workflow)
# publish.yml executa: portão 1 consistência → portão 2 empacotamento → portão 3 higiene → portão 4 teste de fumaça do pacote → testes
#   → tag/versão iguais → guarda de idempotência → OIDC publish --provenance --tag dsh → auditoria posterior
```

## Install

**Como bundle** (recomendado; a entrada registra a skill + as capacidades do grupo C, e a camada patch *pode* montar as ferramentas por nível — **desligadas por padrão**, veja [Model routing](#model-routing)):

```sh
dsh plugin --profile web add lunheng-article-pipeline
dsh --profile web --dump-config   # mostra uma camada "# == lunheng-article-pipeline"
```

Um `dsh` moderno adiciona a dependência a `dsh.profile.bundles` assim que vê a declaração `dsh.bundle`: instale e reinicie o `dsh web`. Somente instalações npm/pnpm puras ou versões antigas precisam da entrada manual.

**Como diretório de skill simples** (sem instalação; o host vigia a raiz de skills e a atualiza a cada mudança — o `SKILL.md` do modo um é um instantâneo lido no `apply` do entry, então editar o conteúdo exige recarregar o plugin ou abrir uma sessão nova):

```sh
# Copie o DIRETÓRIO DA SKILL (não a raiz do repositório) para qualquer raiz de skills:
#   $DSH_HOME/skills/lunheng-article-pipeline        (usuário, rank 400)
#   <projeto>/.dsh/skills/lunheng-article-pipeline   (projeto, rank 100)
```

Um diretório simples não declara `dsh.bundle`, então `dsh plugin add` apenas o instala como dependência e não ativa camada alguma. Copiar o diretório da skill é o caminho suportado.

### Requirements

| Item | Requisito |
|---|---|
| DSH (versão de produto) | `dsh` CLI disponível; as linhas `- insert:` do bundle precisam de **DSH 5.5.0+ versão de produto** — nota: `dsh` é distribuído em duas linhas de versão paralelas, uma **linha de produto** (semver, ex. `5.5.0`) e a **linha npm** `@deepseek-ai/dsh` (tags prerelease, ex. `0.1.7-rc.2`); **não são intercambiáveis** |
| `@deepseek-ai/dsh` (versão npm) | `peerDependencies` declara `>=0.1.2-rc.1 <0.3.0`; **a CI testa `0.1.7-rc.2` e `0.2.1-rc.2`** (matriz `install-smoke` em `ci.yml`); outras versões dentro do intervalo (ex.: `0.2.0-rc.x`, `0.1.3`–`0.1.6`) são **declaradas, não verificadas** |
| Node | `^22.19.0 \|\| >=24.0.0` (mínimo do DSH; ver `engines` no `package.json`) |
| pnpm | Necessário para instalar/desinstalar (`dsh plugin` delega ao pnpm) |
| Plataforma | Windows / macOS / Linux (scripts sem dependências) |

### Uninstall

```sh
dsh plugin --profile <profile> remove lunheng-article-pipeline
```

Ao desinstalar, as 4 linhas `- insert:` (a de autorregistro e as três de nível) e a skill registrada pela entrada desaparecem, sem resíduos. Se você também copiou o diretório da skill para uma raiz de skills, apague essa cópia separadamente.

## Model routing

O DSH roteia modelos por `settings.yaml`; `subagent` herda o modelo da sessão, então uma configuração de modelo único funciona sem ajustes. Para escalonar por papel, o bundle pode montar três ferramentas por nível — **desligadas por padrão** (enquanto todos os níveis herdam, elas são idênticas ao `subagent` embutido, então montá-las sem condição custaria três esquemas de ferramenta por sessão em troca de nada):

| Ferramenta | Papéis | Capacidade |
|---|---|---|
| `subagent_retrieval` | T1 bibliografia / T2 dados / T3 casos | Rápido e barato |
| `subagent_strong` | T4 análise / T5 redação | Raciocínio forte |
| `subagent_audit` | T6 crítica / T7 auditoria / T9 revisão / detector G14 | Nível máximo, sem degradar por custo |

Substitua com `LUNHENG_{RETRIEVAL,STRONG,AUDIT}_PROVIDER` e `LUNHENG_{RETRIEVAL,STRONG,AUDIT}_MODEL`: **definir qualquer uma delas também monta as três linhas** (uma configuração escalonada já existente continua funcionando igual). Provedor e modelo são campos independentes (cruzar provedores exige ambos); `LUNHENG_TIERING=on` monta as linhas sem fixar nenhum modelo (útil para conferir se estão visíveis) e `LUNHENG_TIERING=off` devolve os três níveis à herança e as desmonta. Quando uma ferramenta de nível não está montada, o despacho recai no `subagent` embutido. Veja `examples/preset/README.md` e `docs/installation.md`.

## Data and external services

A pipeline envia o seguinte a terceiros:

| Operação | Conteúdo enviado | Destinatário |
|---|---|---|
| `web_search` / `web_fetch` | Palavras-chave e URL de destino | Os provedores de busca e leitura configurados no DSH |
| Inferência do modelo | Fichas bibliográficas, de dados e de casos; esboços; rascunhos | O provedor de modelo ativo |
| Geração de imagens (opcional, desligada) | Tema e prompt de marca | Um MCP de imagens, apenas se você habilitar |

O coordenador deve divulgar esses envios e obter consentimento explícito na fase 0. Para temas confidenciais: anonimize o texto, mantenha as capas como SVG local (zero chamadas externas) e escolha um endpoint de modelo local. Recusar qualquer item devolve a execução à fase 0.

## Verification status

| Artigo | Escala | Resultado |
|---|---|---|
| Consistência de marca (2026-08) | ~7900 caracteres, 15 fontes + 54 dados | Pacote probatório; 8 achados encerrados |
| Paradoxo da originalidade (2026-08) | ~9500 caracteres, 12 fontes + 34 dados + 6 casos | 4 rodadas de revisão no total ao longo da execução, nota A-, publicado |
| Isolamento do campo docente (2026-08) | ~12000 caracteres, 18 fontes + 47 dados + 9 casos | Auditoria rodada 2 aprovada |
| Escrita estudantil com IA generativa (2026-08) | ~2000 caracteres, 12 fontes + 26 dados | Busca tripla paralela; portão M exit 0 |
| Caso do repolho com formaldeído (2026-08) | ~4200 caracteres, 12 fontes + 29 dados + 4 casos | Portão M exit 0; 6 regras incorporadas |
| Artigo sobre noção e ideia (2026-09) | ~6280 caracteres, 18 fontes + 15 dados, 0 casos | 2 rodadas de auditoria, 23/30 revisão menor, P0 real = 0 |

> **Como ler esta tabela (dois critérios que se confundem facilmente)**: ① «rodadas de revisão» conta **todas as passagens do redator naquela execução** (fase 3.5 → v2, correções da crítica T6, rodadas G14, laço de auditoria), enquanto o limite da própria pipeline (**≤2 rodadas**) vale **apenas para o laço de auditoria da fase 4.2** — os dois números não medem a mesma coisa; ② os resultados são **valores históricos registrados no momento de cada execução, com a versão de scripts daquela época** — não são reproduzíveis com os scripts atuais. Reexecutar hoje os scripts do pacote sobre os projetos arquivados devolve, por exemplo, o artigo do repolho com formaldeído em `exit 2` com 5 P0 (M-Form-6/10, M-Exist-7/9, M-Integrity-1): três desses portões foram acrescentados **depois** daquela execução. Leia a tabela como «o que a pipeline produziu então», não como «o conjunto de portões atual aprova estes projetos».

> **Referências cruzadas (lote de auditoria documental v18.78.0 §7.2)**: análise aprofundada dos 6 casos representativos desta tabela em [`docs/introduction.md` §实战验证](docs/introduction.md) (caso do repolho chinês com formaldeído ~4200 caracteres v2.3.7-dsh.8 + 6 casos do período v18.x); campos completos e caminhos de produtos para casos v2.x em [`references/case-studies.md`](skills/lunheng-article-pipeline/references/case-studies.md) §instantâneo histórico. **Cartão rápido para novatos (lote v18.78.0 §7.2)**: números concretos (versão / papéis / fases / portas / scripts / comandos / família de códigos de saída) fonte única = [`docs/quick-facts.md`](docs/quick-facts.md).

Portões locais (**somente fontes do repositório** — o pacote npm **não inclui** `scripts/` nem `tests/`, portanto os comandos abaixo não rodam numa instalação a partir do pacote; dentro do pacote você pode rodar o conjunto equivalente no tarball recém-baixado via `pack-smoke`): `node skills/lunheng-article-pipeline/scripts/consistency-check.mjs`, `node scripts/plugin-surface-check.mjs`, `node scripts/repo-hygiene-check.mjs`, `node scripts/pack-smoke.mjs`, `node --test "tests/**/*.test.mjs"`.

## Known limitations

- **Prioridade do chinês.** Prompts de papel, entregáveis, nomes de arquivo e fluxos são em chinês por padrão.
- **Sem verificação de rede por padrão.** As checagens numéricas costumam ficar «pendentes de revisão manual» porque fontes pagas não podem ser recuperadas.
- **A independência da auditoria tem custo.** Uma execução completa lança mais de 15 subagentes; o gasto concentra-se em leituras de contexto.
- **O portão M pode dar falsos positivos.** O verificador deve registrar `script_exit_raw` e justificar o veredicto `exit` em vez de editar o documento para forçar exit 0.
- **Não substitui a revisão real.** O relatório T9 é uma simulação pré-submissão.

## License

MIT License
