Compare commits

...

30 Commits

Author SHA1 Message Date
Affaan Mustafa f6d7067ff5 fix(hooks): persist metrics warning dedup 2026-05-17 21:32:08 -04:00
Affaan Mustafa ef13690fc3 fix(hooks): suppress repeated metrics warning breadcrumbs 2026-05-17 21:09:47 -04:00
Jamkris 8cb9dac8ec docs(hooks): correct PreToolUse → PostToolUse in readSessionCost docblock
greptile P2 nitpick: the previous commit's docblock said "on every
PreToolUse hook" but the module header (and the actual hook wiring
in `hooks/hooks.json`) identifies this script as a PostToolUse
hook — it runs *after* each tool invocation to update the running
session aggregate. One-word typo, no behavior change.
2026-05-18 10:03:42 +09:00
Jamkris cd176504d3 fix(hooks): log fail-open breadcrumb on parse/read errors in metrics bridge
coderabbitai flagged: the two `catch` blocks in `readSessionCost`
silently swallowed every failure mode. A malformed `costs.jsonl`
row, a permission error opening the file, or any other unexpected
I/O failure would silently return zero cost — masking real
problems and feeding stale or zero numbers into
`ecc-context-monitor.js` (which then injects them as
`additionalContext` into the live model turn).

Fix two things, both fail-open-preserving:

1. **Inner JSON.parse catch** — count malformed lines and write
   one aggregated breadcrumb per call:

     [ecc-metrics-bridge] skipped N malformed line(s) in <path>

   Aggregating (rather than per-line) keeps a log-flooded
   `costs.jsonl` diagnosable without overwhelming stderr.

2. **Outer fs.readFileSync catch** — write a breadcrumb on real
   errors, but stay silent on `ENOENT`. The "no costs.jsonl yet"
   case is genuinely normal (no Stop event has fired this session)
   and producing noise on every PreToolUse before the first Stop
   would be reviewer-visible spam. All other error codes
   (`EACCES`, `EISDIR`, `EMFILE`, …) get:

     [ecc-metrics-bridge] failing open after <name> reading <path>: <msg>

In both cases the function still returns the zero-cost fallback
so the bridge never breaks tool execution — only the
diagnosability changes.

Two new regression tests in
`tests/hooks/ecc-metrics-bridge.test.js`:

  ✓ readSessionCost writes a stderr breadcrumb when malformed
    lines are skipped — feeds 4 rows (2 valid, 2 malformed),
    asserts the last valid row still wins AND captured stderr
    contains "skipped 2 malformed line(s)".

  ✓ readSessionCost stays silent when costs.jsonl does not exist
    (ENOENT) — uses a fresh tmp HOME with no metrics dir, asserts
    zero return AND empty stderr.

Test count: 16 → 18; `npm test` green; `yarn lint` clean.
2026-05-18 10:03:21 +09:00
Jamkris 44e13541fa fix(hooks): scan full costs.jsonl when locating session row
`readSessionCost` read only the trailing 8 KiB of
`~/.claude/metrics/costs.jsonl` to "avoid scanning entire file".
That ceiling is the opposite-sign sibling of the double-count bug
fixed in the previous commit: once a session's most recent
cumulative row gets pushed past the 8 KiB window by newer rows
from other sessions, the bridge silently reports `totalCost: 0`,
`totalIn: 0`, `totalOut: 0` for that session — same false signal
to `ecc-context-monitor.js`, same wrong number injected into the
live model turn as `additionalContext`.

`cost-tracker.js` has no rotation policy, so on any non-trivial
workstation costs.jsonl grows past 8 KiB within minutes of normal
use. For users who keep multiple concurrent sessions, this means
the second-and-later sessions silently report zero almost
immediately.

Reproduced before this commit:

  $ HOME=/tmp/eccc node -e '
      const fs = require("fs");
      const m = require("./scripts/hooks/ecc-metrics-bridge.js");
      // S1 row at file start, then 200 rows of OTHER-session noise (~16 KiB).
      // S1 is the row we want, but it sits past the 8 KiB tail.
      const s1 = `{"session_id":"S1","estimated_cost_usd":0.5,"input_tokens":500,"output_tokens":250}`;
      const other = `{"session_id":"OTHER","estimated_cost_usd":1,"input_tokens":100,"output_tokens":50}`;
      fs.mkdirSync("/tmp/eccc/.claude/metrics", { recursive: true });
      fs.writeFileSync("/tmp/eccc/.claude/metrics/costs.jsonl",
        [s1, ...Array(200).fill(other)].join("\\n") + "\\n");
      console.log(JSON.stringify(m.readSessionCost("S1")));'
  {"totalCost":0,"totalIn":0,"totalOut":0}

Expected: `{"totalCost":0.5, "totalIn":500, "totalOut":250}` (the
S1 row that exists in the file).
Actual: zero — the row is past the 8 KiB tail.

Fix: drop the `fs.openSync` + bounded `fs.readSync` + position
arithmetic in favour of `fs.readFileSync(costsPath, 'utf8')` and
iterate every line. Each row is ~150 bytes; even 100k rows is
~15 MB and a single sync read on PreToolUse is in the low ms.
If file rotation lands in `cost-tracker.js` later, this scan
becomes proportionally cheaper.

After this commit the reproduction above returns
`{"totalCost":0.5, "totalIn":500, "totalOut":250}`.

Regression test in `tests/hooks/ecc-metrics-bridge.test.js`:
`readSessionCost finds session row beyond the old 8 KiB tail
boundary`. The test asserts the costs.jsonl fixture is > 8 KiB
before reading so any reintroduction of a bounded tail would
re-fail the test (i.e. the assertion is the contract, not the
specific number 8192).

Together with the previous commit, both directions of the
metrics-bridge cost-reporting bug are closed.
2026-05-18 08:45:48 +09:00
Jamkris e61bb043ed fix(hooks): use last cumulative row for session cost in metrics bridge
`ecc-metrics-bridge.js#readSessionCost` summed the
`estimated_cost_usd`, `input_tokens`, and `output_tokens` of
every matching row in `~/.claude/metrics/costs.jsonl`. That breaks
the documented contract of `scripts/hooks/cost-tracker.js`, which
explicitly states (in its module docblock):

  Cumulative behavior: Stop fires per assistant response, not
  per session. Each row therefore represents the cumulative
  session total up to that point. To get per-session cost, take
  the last row per session_id.

Summing N cumulative rows over-counts by roughly (N+1)/2 ×. For a
session with 3 rows at 0.01, 0.02, 0.03 USD (true running total
0.03), the bridge today reports 0.06 USD. The over-counted value
feeds `ecc-context-monitor.js`, which then trips its
COST_NOTICE_USD / COST_WARNING_USD / COST_CRITICAL_USD thresholds
on phantom spend AND injects the inflated number as
`additionalContext` into the live model turn — so the agent
itself is told a wrong cost.

Reproduced on `main` before this commit:

  $ cat > /tmp/eccc/.claude/metrics/costs.jsonl <<EOF
  {"session_id":"S1","estimated_cost_usd":0.01,"input_tokens":333,"output_tokens":166}
  {"session_id":"S1","estimated_cost_usd":0.02,"input_tokens":666,"output_tokens":333}
  {"session_id":"S1","estimated_cost_usd":0.03,"input_tokens":1000,"output_tokens":500}
  EOF

  $ HOME=/tmp/eccc node -e 'const m = require("./scripts/hooks/ecc-metrics-bridge.js"); \
      console.log(JSON.stringify(m.readSessionCost("S1")))'
  {"totalCost":0.06,"totalIn":1999,"totalOut":999}

Expected: `{"totalCost":0.03,"totalIn":1000,"totalOut":500}` (the
last cumulative row).
Actual: 2× over-count.

Fix: replace `+=` with `=` in the matching branch so the assigned
values reflect the most recent row encountered. The iteration
order is file order, which is also event time order, so the last
assignment wins — exactly the contract cost-tracker writes
against.

After this commit the reproduction above returns
`{"totalCost":0.03,"totalIn":1000,"totalOut":500}`.

Regression test in `tests/hooks/ecc-metrics-bridge.test.js`:
`readSessionCost returns the LAST cumulative row, not the sum
(cost-tracker contract)`. The existing
`readSessionCost does not include unrelated default-session rows`
test happened to pass even with the bug because it only had one
target-session row — single-row sessions are coincidentally
correct under both formulas. The new test uses three rows so the
two formulas diverge.

A second issue in the same function — the 8 KiB tail-only read
silently drops older rows once a session's recent cumulative
totals scroll past that window — is fixed in the next commit.
2026-05-18 08:45:48 +09:00
Affaan Mustafa b113edac4b docs: remove personal paths from rc1 evidence 2026-05-17 18:02:23 -04:00
Affaan Mustafa a9c8c3ed76 docs: refresh rc1 evidence after security recheck 2026-05-17 17:59:17 -04:00
Affaan Mustafa e6c16b40b8 docs: refresh rc1 dashboard after security hardening 2026-05-17 17:57:37 -04:00
Affaan Mustafa 36d390aa7d security: cover gh-token-monitor token persistence 2026-05-17 17:46:35 -04:00
Affaan Mustafa 6b282aaa43 docs(th): address README review nits 2026-05-17 17:28:06 -04:00
Roongroj P 989559a728 docs(th): add Thai (th) README translation
Adds docs/th/README.md with a concise onboarding-style Thai
translation mirroring the docs/vi-VN format. Updates the language
switchers in the English, Simplified Chinese, Traditional Chinese,
Japanese, Korean, Portuguese (BR), Russian, Turkish, Vietnamese,
and Simplified Chinese docs READMEs to link to the new Thai page.

The English README remains the canonical source of truth; the Thai
page links back to it for full content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 17:28:06 -04:00
Affaan Mustafa 3539bdbef6 Refresh rc1 launch readiness copy 2026-05-17 16:43:04 -04:00
Affaan Mustafa 27dc2918a2 Regenerate preview pack readiness dashboard after lint fix 2026-05-17 15:41:19 -04:00
Affaan Mustafa 822ed726a8 Fix preview pack smoke lint 2026-05-17 15:40:29 -04:00
Affaan Mustafa fd7c7cf47f Regenerate preview pack readiness dashboard 2026-05-17 15:36:41 -04:00
Affaan Mustafa 3215e655ef Add preview pack smoke gate 2026-05-17 15:35:23 -04:00
Affaan Mustafa 1a384dc533 Regenerate Linear progress readiness dashboard 2026-05-17 15:14:40 -04:00
Affaan Mustafa 355c4f12cf Refresh Linear progress readiness detection 2026-05-17 15:13:42 -04:00
Affaan Mustafa 5c135fb846 Regenerate legacy readiness dashboard 2026-05-17 14:49:05 -04:00
Affaan Mustafa f397216aa0 Track legacy localization tail in readiness dashboard 2026-05-17 14:47:29 -04:00
Affaan Mustafa 7b2f0125bb Regenerate operator readiness dashboard 2026-05-17 14:29:55 -04:00
Affaan Mustafa f9bf94b246 Refresh operator dashboard readiness markers 2026-05-17 14:28:16 -04:00
Affaan Mustafa ffcde01e4b docs: record marketplace readback state 2026-05-17 14:09:48 -04:00
Affaan Mustafa 4ca31057c6 docs: record billing announcement preflight 2026-05-17 13:53:20 -04:00
Affaan Mustafa fa7f8e2287 docs: record hosted promotion judge audit traces 2026-05-17 13:37:47 -04:00
Affaan Mustafa 3aab0a67f4 docs: record policy promotion operator telemetry 2026-05-17 13:13:53 -04:00
Affaan Mustafa ddc1e45f2a docs: record policy promotion hosted telemetry 2026-05-17 12:52:30 -04:00
Affaan Mustafa c8a66e13d4 docs: record AgentShield promotion action outputs 2026-05-17 12:12:18 -04:00
Affaan Mustafa 3dc884acf2 docs: record AgentShield hardening action outputs 2026-05-17 11:07:27 -04:00
37 changed files with 1827 additions and 156 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md)
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md)
# Everything Claude Code
@@ -28,7 +28,7 @@
**Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ**
[**English**](README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md)
| [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md)
| [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md)
</div>
+1 -1
View File
@@ -23,7 +23,7 @@
**Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ**
[**English**](README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md)
[**English**](README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md)
</div>
+55 -24
View File
@@ -246,11 +246,25 @@ As of 2026-05-17:
provider only after hosted retrieval evidence, entitlement, budget, provider,
and executor gates pass; the check remains non-blocking, strict-JSON-only,
and rejects uncited or non-hosted model output without echoing raw responses.
- ECC-Tools commit `05d4e8296e37ba72e471beaa23ea4c81eb2aa31f`
adds operator-readable audit traces to hosted promotion model judging:
check-runs now render a deterministic request fingerprint and
allowed-citation count alongside the accepted decision, without exposing raw
provider output.
- ECC-Tools PR #73 merged as `7d0538c9354e18adbfc72ef00d858949a817fa48`
and added a fail-closed native-payments announcement gate to
`/api/billing/readiness`: public payment claims now require
`announcementGate.ready === true` from a Marketplace-managed test account
before launch copy can move past release review.
- ECC-Tools commit `91a441b92342b842832ac28b018ee46f0c4a906f`
adds `npm run billing:announcement-gate -- --preflight` so operators can
verify the Marketplace test account, internal API token presence, and
billing-readiness endpoint before making the privileged readback call.
- ECC-Tools commit `eb6941290b2fa70db01a51084e9e79a160238468`
records live production readback state: Cloudflare Worker secret names include
`INTERNAL_API_SECRET`, but the production KV namespace currently has no
`account-billing:*` or `billing-state:*` records, so no
Marketplace-managed account can pass the announcement gate yet.
- Handoff `ecc-supply-chain-audit-20260513-0645.md` under
`~/.cluster-swarm/handoffs/`
records the May 13 supply-chain sweep: no active lockfile/manifest hit for
@@ -310,8 +324,8 @@ As of 2026-05-17:
and classifies `legacy-command-shims/` as an opt-in archive/no-action
surface.
- `docs/stale-pr-salvage-ledger.md` records stale PR salvage outcomes,
skipped PRs, superseded work, and the remaining #1687 translator/manual
review tail.
skipped PRs, superseded work, and the remaining #1687, #1609, #1563, #1564,
and #1565 translator/manual review tail now attached to Linear ITO-55.
- AgentShield PR #53 reduced two context-rule false positives and closed the
remaining AgentShield issues.
- AgentShield PR #55 added GitHub Action organization-policy enforcement with
@@ -557,6 +571,14 @@ As of 2026-05-17:
`git diff --check`; GitHub Actions run `25986719058`, Test GitHub Action run
`25986719054`, and AgentShield Self-Scan run `25986719066` completed
successfully.
- AgentShield main commit `1124535345d7040242ecd3803f65bcd4dcaf6ec2`
exposes package-manager hardening through the GitHub Action so CI/hosted
consumers can route registry credential, lifecycle-script, and release-age
gate drift separately from generic finding counts. Local validation passed
focused action tests, `npm run typecheck`, `npm run lint`, `npm run build`,
full `npm test`, and `git diff --check`; GitHub Actions CI run
`25994354007`, Test GitHub Action run `25994354011`, and AgentShield
Self-Scan run `25994354026` completed successfully.
- ECC PR #1803 landed the contributor Quarkus handling branch after maintainer
cleanup, current-`main` alignment, full local validation, and preservation of
the author's removal of incomplete ja-JP and zh-CN Quarkus translations.
@@ -603,14 +625,14 @@ is not complete unless the evidence column exists and has been freshly verified.
| Keep public issues below 20 | Repo-family issue recheck | 0 open issues across `everything-claude-code`, AgentShield, JARVIS, `ECC-Tools/ECC-Tools`, and `ECC-Tools/ECC-website` on 2026-05-17; #1951 closed with #1953 | Complete |
| Manage repository discussions | Repo-family discussion recheck | Platform audit reports 0 discussion maintainer-touch gaps and 0 answerable Q&A missing accepted answers; trunk still has 58 total discussions | Complete |
| Manage PR discussions | PR review/comment closure plus merge/close state | ECC #1961, #1963, and #1953 merged after maintainer validation; no open tracked PRs remain | Complete |
| Salvage useful stale work | `docs/stale-pr-salvage-ledger.md` | Ledger records salvaged, superseded, skipped, and manual-review tails; #1815-#1818 added cost tracking, skill scout, frontend design guidance, code-reviewer false-positive guardrails, and the May 12 gap pass | Complete except translation/manual review tail |
| Salvage useful stale work | `docs/stale-pr-salvage-ledger.md` plus `docs/legacy-artifact-inventory.md` | Ledger records salvaged, superseded, skipped, and manual-review tails; #1815-#1818 added cost tracking, skill scout, frontend design guidance, code-reviewer false-positive guardrails, and the May 12 gap pass; #1687, #1609, #1563, #1564, and #1565 localization tails are attached to Linear ITO-55 for language-owner review and no automatic import remains release-blocking | Complete; repeat legacy scan before release |
| ECC 2.0 preview pack ready | Release docs, quickstart, publication readiness, release notes | `docs/releases/2.0.0-rc.1/` and readiness docs are in-tree; May 17 evidence records queue-zero state, localized docs merge, supply-chain recheck, lint/test/security gates, operator dashboard, and successful GitHub CI on `99dd6ac0` | Needs final clean-checkout release approval |
| Hermes specialized skills included safely | Hermes setup/import docs and sanitized skill surface | Hermes setup and import playbook are public; secrets stay local | Needs final release review |
| Naming and rename readiness | Naming matrix across package/plugin/docs/social surfaces | `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` records current package, repo, Claude plugin, Codex plugin, OpenCode, and npm availability evidence | Complete for rc.1; post-rc rename remains future work |
| Claude and Codex plugin publication | Contact/submission path with required artifacts and status | Publication readiness, naming matrix, and May 12 dry-run evidence document plugin validation, clean-checkout Claude tag/install smoke, and Codex marketplace CLI shape | Needs explicit approval for real tag/push and marketplace submission |
| Articles, tweets, and announcements | X thread, LinkedIn copy, GitHub release copy, push checklist | Draft launch collateral exists under rc.1 release docs | Needs URL-backed refresh |
| AgentShield enterprise iteration | Policy gates, SARIF, packs, provenance, corpus, HTML reports, exception lifecycle audit, baseline drift Action/CLI surfaces, evidence-pack redaction, harness adapter registry, enterprise research roadmap, supply-chain hardened release path, CI-safe baseline fingerprints, corpus accuracy recommendations, remediation workflow phases, env proxy hijack corpus coverage, Mini Shai-Hulud full-campaign package IOCs, CI-provenance evidence packs, plugin-cache runtime-confidence triage, evidence-pack consumer readback, fleet-level evidence-pack routing, fleet review items, checksum-backed policy export, checksum-verified policy promotion, and policy promotion review items, package-manager hardening drift detection, npm age-gate guidance correction, and workflow action-runtime pin refresh | PRs #53, #55-#64, #67-#69, and #78-#92 landed with test evidence, ECC-Tools #76 consumes the fleet-summary output in hosted security review, #77 surfaces source evidence paths in hosted finding output, and #78 links fleet routes to harness owner review; AgentShield #91 adds `agentshield policy export` bundles for branch-protection review and downstream promotion; AgentShield #92 adds `agentshield policy promote` with digest verification, tamper rejection, explicit pack selection, dry-run review, and JSON output before writing active policy; AgentShield commit `87aec47` adds `reviewItems` for digest evidence, owner review, protected rollout PR handoff, and runtime smoke testing with green local and remote CI; AgentShield commit `28d08c7` adds package-manager hardening drift detection for plaintext registry credentials, lifecycle-script enablement, and weak pnpm/Yarn release-age cooldowns with green local and remote CI; AgentShield commit `659f569` refreshes all workflow action runtime pins to SHA-pinned checkout v6.0.2 and setup-node v6.4.0 with green remote CI and no remaining action-runtime deprecation annotation; AgentShield commit `ee585cd` corrects npm release-age guidance by flagging unsupported npm age keys and keeping enforceable cooldown findings on pnpm/Yarn with green local and remote CI; native PDF export deferred in favor of self-contained HTML plus print-to-PDF until explicit enterprise demand appears; `docs/architecture/agentshield-enterprise-research-roadmap.md` now has baseline drift, evidence-pack bundle, redaction, adapter-registry, supply-chain hardening, hashed baseline fingerprints, corpus accuracy recommendation, remediation workflow, env proxy hijack corpus, Mini Shai-Hulud full-campaign package-table, `ci-context.json` provenance, `plugin-cache` confidence, `evidence-pack inspect` readback, `evidence-pack fleet` routing, fleet `reviewItems`, policy export, policy promotion, and policy promotion `reviewItems` landed | Next workflow automation should consume promotion `reviewItems`, package-manager hardening findings, and unsupported npm age-key findings in CI/hosted review surfaces and record runtime smoke evidence |
| ECC Tools next-level app | Billing audit, PR checks, deep analyzer, sync backlog, evaluator/RAG corpus, analysis-depth readiness, hosted execution planning, hosted CI diagnostics, hosted security evidence review, hosted harness compatibility audit, hosted reference-set evaluation, hosted AI routing/cost review, hosted team backlog routing, hosted depth-plan check-run, PR-comment hosted job dispatch, hosted job result history/check-runs, hosted result status command, status-aware depth-plan recommendations, hosted promotion readiness, hosted promotion output scoring, hosted promotion retrieval planning, hosted promotion judge contract, gated hosted promotion judge execution, payment-announcement readiness, AgentShield fleet-summary hosted routing, hosted finding source-evidence surfacing, and harness policy-route review | PRs #26-#43 plus #53-#78 landed with test evidence, including AgentShield evidence-pack gap routing, canonical bundle recognition, supply-chain signature gates, PR draft follow-up Linear tracking, evidence-backed/deep-ready repository classification, the `/api/analysis/depth-plan` hosted job plan, `/api/analysis/jobs/ci-diagnostics`, `/api/analysis/jobs/security-evidence-review`, `/api/analysis/jobs/harness-compatibility-audit`, `/api/analysis/jobs/reference-set-evaluation`, `/api/analysis/jobs/ai-routing-cost-review`, `/api/analysis/jobs/team-backlog-routing`, the `ECC Tools / Hosted Depth Plan` check-run, `/ecc-tools analyze --job ...` PR-comment dispatch, non-blocking per-hosted-job result check-runs backed by 30-day result cache records, `/ecc-tools analyze --job status` cache lookup, cache-aware next-job recommendations in the depth-plan check-run, the `ECC Tools / Hosted Promotion Readiness` corpus-backed PR check-run, deterministic hosted-output scoring against cached completed job artifacts/findings, ranked retrieval/model-prompt planning, the fail-closed `hosted-promotion-judge.v1` request contract, opt-in live model-judge execution behind hosted evidence, entitlement, budget, provider, executor, strict JSON, and citation gates, a fail-closed `/api/billing/readiness` `announcementGate` for native GitHub payments claims, `npm run billing:announcement-gate` as the non-secret operator verifier, hosted security findings for AgentShield fleet summaries, an `Evidence` column in hosted finding comments/check-runs, and hosted harness findings that route AgentShield fleet target paths to harness owners | Next work is hosted promotion telemetry, richer operator review UX, and live Marketplace test-account readback |
| AgentShield enterprise iteration | Policy gates, SARIF, packs, provenance, corpus, HTML reports, exception lifecycle audit, baseline drift Action/CLI surfaces, evidence-pack redaction, harness adapter registry, enterprise research roadmap, supply-chain hardened release path, CI-safe baseline fingerprints, corpus accuracy recommendations, remediation workflow phases, env proxy hijack corpus coverage, Mini Shai-Hulud full-campaign package IOCs, CI-provenance evidence packs, plugin-cache runtime-confidence triage, evidence-pack consumer readback, fleet-level evidence-pack routing, fleet review items, checksum-backed policy export, checksum-verified policy promotion, policy promotion review items, package-manager hardening drift detection, npm age-gate guidance correction, workflow action-runtime pin refresh, package-manager hardening Action outputs, policy-promotion Action outputs, ECC-Tools hosted consumption of promotion Action outputs, ECC-Tools operator-visible promotion output values, and ECC-Tools hosted promotion judge audit traces | PRs #53, #55-#64, #67-#69, and #78-#92 landed with test evidence, ECC-Tools #76 consumes the fleet-summary output in hosted security review, #77 surfaces source evidence paths in hosted finding output, and #78 links fleet routes to harness owner review; AgentShield #91 adds `agentshield policy export` bundles for branch-protection review and downstream promotion; AgentShield #92 adds `agentshield policy promote` with digest verification, tamper rejection, explicit pack selection, dry-run review, and JSON output before writing active policy; AgentShield commit `87aec47` adds `reviewItems` for digest evidence, owner review, protected rollout PR handoff, and runtime smoke testing with green local and remote CI; AgentShield commit `28d08c7` adds package-manager hardening drift detection for plaintext registry credentials, lifecycle-script enablement, and weak pnpm/Yarn release-age cooldowns with green local and remote CI; AgentShield commit `659f569` refreshes all workflow action runtime pins to SHA-pinned checkout v6.0.2 and setup-node v6.4.0 with green remote CI and no remaining action-runtime deprecation annotation; AgentShield commit `ee585cd` corrects npm release-age guidance by flagging unsupported npm age keys and keeping enforceable cooldown findings on pnpm/Yarn with green local and remote CI; AgentShield commit `1124535` exposes package-manager hardening status/count outputs and a redacted job-summary section for registry credentials, lifecycle scripts, and release-age gates with green local and remote CI; AgentShield commit `1593925` exposes policy-promotion status/count/digest outputs plus job-summary review items for owner approval, protected rollout, and runtime smoke, and marks runtime smoke verified when the same Action job scans with the promoted policy; ECC-Tools commit `8658951` routes those policy-promotion Action outputs into hosted security review findings and Hosted Promotion Readiness scoring; ECC-Tools commit `16c537f` renders policy-promotion status, pack, review item count, action-required count, and digest in hosted security job comments/check-runs; ECC-Tools commit `05d4e82` renders hosted promotion judge request fingerprints and allowed-citation counts without raw provider output; native PDF export deferred in favor of self-contained HTML plus print-to-PDF until explicit enterprise demand appears; `docs/architecture/agentshield-enterprise-research-roadmap.md` now has baseline drift, evidence-pack bundle, redaction, adapter-registry, supply-chain hardening, hashed baseline fingerprints, corpus accuracy recommendation, remediation workflow, env proxy hijack corpus, Mini Shai-Hulud full-campaign package-table, `ci-context.json` provenance, `plugin-cache` confidence, `evidence-pack inspect` readback, `evidence-pack fleet` routing, fleet `reviewItems`, policy export, policy promotion, policy promotion `reviewItems`, package-manager hardening Action outputs, policy-promotion Action outputs, hosted consumption of promotion Action outputs, operator-visible promotion output values, and hosted promotion judge audit traces landed | Next workflow automation should deepen live operator approval/readback after Marketplace/payment gates |
| ECC Tools next-level app | Billing audit, PR checks, deep analyzer, sync backlog, evaluator/RAG corpus, analysis-depth readiness, hosted execution planning, hosted CI diagnostics, hosted security evidence review, hosted harness compatibility audit, hosted reference-set evaluation, hosted AI routing/cost review, hosted team backlog routing, hosted depth-plan check-run, PR-comment hosted job dispatch, hosted job result history/check-runs, hosted result status command, status-aware depth-plan recommendations, hosted promotion readiness, hosted promotion output scoring, hosted promotion retrieval planning, hosted promotion judge contract, gated hosted promotion judge execution, hosted promotion judge audit trace, payment-announcement readiness, billing announcement preflight, production Marketplace readback state, AgentShield fleet-summary hosted routing, hosted finding source-evidence surfacing, harness policy-route review, policy-promotion Action-output hosted telemetry, and operator-visible promotion output values | PRs #26-#43 plus #53-#78 landed with test evidence, including AgentShield evidence-pack gap routing, canonical bundle recognition, supply-chain signature gates, PR draft follow-up Linear tracking, evidence-backed/deep-ready repository classification, the `/api/analysis/depth-plan` hosted job plan, `/api/analysis/jobs/ci-diagnostics`, `/api/analysis/jobs/security-evidence-review`, `/api/analysis/jobs/harness-compatibility-audit`, `/api/analysis/jobs/reference-set-evaluation`, `/api/analysis/jobs/ai-routing-cost-review`, `/api/analysis/jobs/team-backlog-routing`, the `ECC Tools / Hosted Depth Plan` check-run, `/ecc-tools analyze --job ...` PR-comment dispatch, non-blocking per-hosted-job result check-runs backed by 30-day result cache records, `/ecc-tools analyze --job status` cache lookup, cache-aware next-job recommendations in the depth-plan check-run, the `ECC Tools / Hosted Promotion Readiness` corpus-backed PR check-run, deterministic hosted-output scoring against cached completed job artifacts/findings, ranked retrieval/model-prompt planning, the fail-closed `hosted-promotion-judge.v1` request contract, opt-in live model-judge execution behind hosted evidence, entitlement, budget, provider, executor, strict JSON, and citation gates, hosted promotion judge request fingerprints plus allowed-citation audit trails, a fail-closed `/api/billing/readiness` `announcementGate` for native GitHub payments claims, `npm run billing:announcement-gate` plus `--preflight` as the non-secret operator verifier, hosted security findings for AgentShield fleet summaries, an `Evidence` column in hosted finding comments/check-runs, hosted harness findings that route AgentShield fleet target paths to harness owners, ECC-Tools commit `8658951` routing AgentShield policy-promotion Action outputs into hosted security review and promotion-readiness scoring, ECC-Tools commit `16c537f` rendering policy-promotion status/pack/count/digest values directly in hosted security job comments/check-runs, ECC-Tools commit `05d4e82` rendering model-judge audit traces without exposing raw provider output, ECC-Tools commit `91a441b` adding the safe billing announcement preflight path, and ECC-Tools commit `eb69412` recording that production has no Marketplace billing-state KV records yet | Next work is complete Marketplace purchase/webhook readback, then run the live announcement gate |
| GitGuardian/Dependabot/CodeRabbit-style checks | Non-blocking taxonomy, deterministic follow-up checks, and local supply-chain gates | ECC-Tools risk taxonomy check plus follow-up signals landed, including Skill Quality, Deep Analyzer Evidence, Analyzer Corpus Evidence, RAG/Evaluator Evidence, PR Review/Salvage Evidence, and AgentShield evidence-pack evidence; #1846 added npm registry signature gates; #1848 added the supply-chain incident-response playbook and `pull_request_target` cache-poisoning validator guard; #1851 added the privileged checkout credential-persistence guard; AgentShield #78, JARVIS #13, and ECC-Tools #53 applied the same hardening outside trunk | Current supply-chain gate complete; deeper hosted review features remain future |
| Harness-agnostic learning system | Audit, adapter matrix, observability, traces, promotion loop | Audit/adapters/observability gates plus `docs/architecture/evaluator-rag-prototype.md`, `examples/evaluator-rag-prototype/`, and ECC-Tools PR #40 define read-only stale-salvage, billing-readiness, CI-failure-diagnosis, harness-config-quality, AgentShield policy-exception, skill-quality evidence, deep-analyzer evidence, and RAG/evaluator comparison scenarios with trace, report, playbook, verifier, and predictive-check artifacts; ECC-Tools PRs #68-#72 now turn that corpus into a deterministic PR check-run gate with cached hosted-output scoring, ranked retrieval candidates, a model prompt seed, a fail-closed hosted model-judge request contract, and opt-in live model execution behind strict hosted-evidence gates | Deterministic hosted PR check, cached output scoring, retrieval planning, judge contract, and gated model execution integrated |
| Linear roadmap is detailed | Linear project status plus repo mirror | Repo mirror exists; issue creation was retried on 2026-05-12 and remains blocked by the workspace free issue limit; the May 17 sync adds the queue-zero batch, Japanese localization merge, ITO-57 live supply-chain refresh comment, ECC platform project progress snapshot, and generated `operator:dashboard` prompt-to-artifact audit for recurring status updates | Needs recurring status updates after each significant merge batch |
@@ -632,9 +654,9 @@ repo evidence and merge commits.
| Queue hygiene and salvage | GitHub PR/issue state, salvage ledger | Append ledger entries for any future stale closures | Every cleanup batch |
| Release and publication | rc.1 release docs, publication readiness doc | Naming matrix and plugin submission/contact checklist | Before any tag |
| Harness OS core | Audit, adapter matrix, observability docs, `ecc2/` | HUD/session-control acceptance spec | Weekly until GA |
| Evaluation and RAG | Reference-set validation, harness audit, traces, ECC-Tools corpus | Read-only evaluator/RAG prototype plus stale-salvage, billing-readiness, CI-failure-diagnosis, harness-config-quality, AgentShield policy-exception, skill-quality evidence, deep-analyzer evidence, and RAG/evaluator comparison fixtures; ECC-Tools #68 publishes the corpus as a hosted promotion readiness check-run, #69 scores cached hosted job outputs against the same corpus, #70 emits ranked retrieval candidates plus a model prompt seed, #71 adds a fail-closed hosted model-judge request contract, and #72 executes that judge only when explicitly enabled and backed by hosted retrieval citations | Hosted promotion telemetry and operator review UX |
| AgentShield enterprise | AgentShield PR evidence and roadmap notes | Fleet routing landed in #89 after evidence-pack inspect/readback shipped in #88; #90 emits fleet `reviewItems`; #91 exports checksum-backed policy bundles; #92 promotes checksum-verified policies from those bundles into active policy files; AgentShield `87aec47` adds policy promotion `reviewItems`; `28d08c7` adds package-manager hardening drift detection; `659f569` refreshes workflow action runtime pins; `ee585cd` corrects unsupported npm release-age guidance and keeps enforceable cooldown findings on pnpm/Yarn; ECC-Tools #76 consumes fleet summaries, #77 surfaces source evidence paths in hosted findings, and #78 links fleet routes to harness owners | Consume promotion `reviewItems`, package-manager hardening findings, and unsupported npm age-key findings in workflow automation and hosted/runtime review UX |
| ECC Tools app | ECC-Tools PR evidence, billing audit, risk taxonomy, evaluator/RAG corpus | ECC-Tools #53 published the supply-chain workflow hardening branch, #54 tracks copy-ready PR drafts in the Linear/project backlog, #55 classifies analysis-depth readiness, #56 exposes the hosted execution plan, #57 executes the first hosted CI diagnostics job, #58 executes the hosted security evidence review job, #59 executes the hosted harness compatibility audit, #60 executes the hosted reference-set evaluation, #61 executes the hosted AI routing/cost review, #62 executes hosted team backlog routing, #63 publishes the hosted depth-plan check-run, #64 dispatches hosted jobs from PR comments, #65 persists hosted result history/check-runs, #66 exposes hosted job status from PR comments, #67 makes depth-plan recommendations cache-aware, #68 publishes hosted promotion readiness from the evaluator/RAG corpus, #69 scores cached hosted job outputs against that corpus, #70 emits ranked retrieval candidates plus a model prompt seed, #71 emits the gated `hosted-promotion-judge.v1` contract without live model calls, #72 adds opt-in live model-judge execution behind hosted-evidence and strict JSON/citation gates, #73 adds a fail-closed native-payments `announcementGate` to billing readiness, #74 adds `npm run billing:announcement-gate` for operator verification, #75 tightens the billing announcement gate for live Marketplace readback, #76 routes AgentShield fleet-summary evidence into hosted security findings, #77 adds source evidence paths to hosted finding output, and #78 links AgentShield fleet target paths to hosted harness owner findings | Live Marketplace test-account readback, hosted promotion telemetry, and richer operator review UX |
| Evaluation and RAG | Reference-set validation, harness audit, traces, ECC-Tools corpus | Read-only evaluator/RAG prototype plus stale-salvage, billing-readiness, CI-failure-diagnosis, harness-config-quality, AgentShield policy-exception, skill-quality evidence, deep-analyzer evidence, and RAG/evaluator comparison fixtures; ECC-Tools #68 publishes the corpus as a hosted promotion readiness check-run, #69 scores cached hosted job outputs against the same corpus, #70 emits ranked retrieval candidates plus a model prompt seed, #71 adds a fail-closed hosted model-judge request contract, and #72 executes that judge only when explicitly enabled and backed by hosted retrieval citations; ECC-Tools `16c537f` surfaces policy-promotion Action output values in hosted security comments/checks; ECC-Tools `05d4e82` adds hosted model-judge audit traces with request fingerprints and allowed-citation counts | Marketplace readback |
| AgentShield enterprise | AgentShield PR evidence and roadmap notes | Fleet routing landed in #89 after evidence-pack inspect/readback shipped in #88; #90 emits fleet `reviewItems`; #91 exports checksum-backed policy bundles; #92 promotes checksum-verified policies from those bundles into active policy files; AgentShield `87aec47` adds policy promotion `reviewItems`; `28d08c7` adds package-manager hardening drift detection; `659f569` refreshes workflow action runtime pins; `ee585cd` corrects unsupported npm release-age guidance and keeps enforceable cooldown findings on pnpm/Yarn; `1124535` exposes package-manager hardening Action outputs for CI/hosted routing; `1593925` exposes policy-promotion Action outputs and runtime-smoke job-summary evidence; ECC-Tools #76 consumes fleet summaries, #77 surfaces source evidence paths in hosted findings, #78 links fleet routes to harness owners, ECC-Tools `8658951` consumes policy-promotion Action outputs, and ECC-Tools `16c537f` renders operator-visible output values | Deepen live operator approval/readback after Marketplace/payment gates |
| ECC Tools app | ECC-Tools PR evidence, billing audit, risk taxonomy, evaluator/RAG corpus | ECC-Tools #53 published the supply-chain workflow hardening branch, #54 tracks copy-ready PR drafts in the Linear/project backlog, #55 classifies analysis-depth readiness, #56 exposes the hosted execution plan, #57 executes the first hosted CI diagnostics job, #58 executes the hosted security evidence review job, #59 executes the hosted harness compatibility audit, #60 executes the hosted reference-set evaluation, #61 executes the hosted AI routing/cost review, #62 executes hosted team backlog routing, #63 publishes the hosted depth-plan check-run, #64 dispatches hosted jobs from PR comments, #65 persists hosted result history/check-runs, #66 exposes hosted job status from PR comments, #67 makes depth-plan recommendations cache-aware, #68 publishes hosted promotion readiness from the evaluator/RAG corpus, #69 scores cached hosted job outputs against that corpus, #70 emits ranked retrieval candidates plus a model prompt seed, #71 emits the gated `hosted-promotion-judge.v1` contract without live model calls, #72 adds opt-in live model-judge execution behind hosted-evidence and strict JSON/citation gates, #73 adds a fail-closed native-payments `announcementGate` to billing readiness, #74 adds `npm run billing:announcement-gate` for operator verification, #75 tightens the billing announcement gate for live Marketplace readback, #76 routes AgentShield fleet-summary evidence into hosted security findings, #77 adds source evidence paths to hosted finding output, #78 links AgentShield fleet target paths to hosted harness owner findings, `8658951` routes AgentShield policy-promotion Action outputs into hosted security review and promotion readiness, `16c537f` renders policy-promotion status/pack/count/digest values in hosted security comments/checks, `05d4e82` renders hosted promotion judge request fingerprints plus allowed-citation audit traces, `91a441b` adds billing announcement preflight output for required readback inputs, and `eb69412` records the live production KV readback state | Marketplace purchase/webhook readback, then live announcement gate |
| Linear progress | Linear project status updates, `docs/architecture/progress-sync-contract.md`, generated `operator:dashboard` output, and this mirror | Status update with queue/evidence/missing gates | Every significant merge batch |
The project status update should always include:
@@ -870,21 +892,30 @@ Acceptance:
owner-review, protected-rollout PR handoff, and runtime smoke testing;
AgentShield commit `28d08c7` adds package-manager hardening drift detection;
AgentShield commit `659f569` clears the action-runtime deprecation warnings
with current SHA-pinned v6 actions; and AgentShield commit `ee585cd`
corrects npm release-age guidance so unsupported npm age keys are findings
while enforceable cooldown findings stay on pnpm/Yarn. The next slice is
workflow automation that consumes promotion `reviewItems`, package-manager
hardening findings, and unsupported npm age-key findings in CI, hosted
review, and runtime smoke evidence surfaces.
2. Run ECC-Tools `/api/billing/readiness` against a Marketplace-managed test
account and require `announcementGate.ready === true` before any native
GitHub payments announcement.
3. Add hosted promotion telemetry and operator review UX on top of the #72
gated model execution path so live judgments can be audited before any
promotion policy becomes enforceable.
4. Enable/configure the merged Linear backlog sync path after workspace issue
with current SHA-pinned v6 actions; AgentShield commit `ee585cd` corrects
npm release-age guidance so unsupported npm age keys are findings while
enforceable cooldown findings stay on pnpm/Yarn; AgentShield commit
`1124535` exposes package-manager hardening Action outputs for registry
credentials, lifecycle-script drift, and release-age gate drift; and
AgentShield commit `1593925` exposes policy-promotion Action outputs for
owner approval, protected rollout, digest evidence, and runtime-smoke
review items, ECC-Tools commit `8658951` consumes those outputs in hosted
security review and Hosted Promotion Readiness scoring, and ECC-Tools
commit `16c537f` renders promotion status, pack, review item count,
remaining action count, and digest in hosted security comments/check-runs.
ECC-Tools commit `05d4e82` adds hosted promotion judge audit traces with
deterministic request fingerprints and allowed-citation counts, without
exposing raw provider output.
ECC-Tools commit `91a441b` adds a billing announcement preflight command
for checking Marketplace readback inputs before privileged API calls.
The next slice is live operator approval/readback after Marketplace/payment
gates.
2. Run `npm run billing:announcement-gate -- --preflight --account
<github-login>`, then run the same command without `--preflight` against a
Marketplace-managed test account and require `announcementGate.ready ===
true` before any native GitHub payments announcement.
3. Enable/configure the merged Linear backlog sync path after workspace issue
capacity clears or the Linear workspace is upgraded, then verify PR-draft
salvage items land in the expected project.
5. Use the ECC-Tools evaluator/RAG corpus as the promotion gate before adding
hosted retrieval, vector storage, live model-backed judging, or automated
check-run promotion.
4. Use the ECC-Tools evaluator/RAG corpus as the promotion gate before adding
deeper hosted retrieval, vector storage, or automated check-run promotion.
+2 -2
View File
@@ -1,4 +1,4 @@
**言語:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
**言語:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
# Everything Claude Code
@@ -21,7 +21,7 @@
**言語 / Language / 語言 / Dil / Язык / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+2 -2
View File
@@ -1,4 +1,4 @@
**언어:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | 한국어 | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
**언어:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | 한국어 | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
# Everything Claude Code
@@ -24,7 +24,7 @@
**Language / 语言 / 語言 / 언어 / Dil / Язык / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+5 -1
View File
@@ -54,7 +54,11 @@ Expected result:
| `_legacy-documents-*` directories | Archive/no-action | No matching directories exist in the tracked checkout as of 2026-05-12. | Re-run the scan before release. If any appear, add each directory to this table before publishing. |
| `legacy-command-shims/` | Archive/no-action | `legacy-command-shims/README.md` states these retired short-name shims are opt-in and no longer loaded by the default plugin command surface. | Keep as an explicit compatibility archive. Do not move these back into the default plugin surface without a migration decision. |
| Closed-stale PR salvage ledger | Landed | `docs/stale-pr-salvage-ledger.md` records useful stale work recovered through maintainer PRs. | Continue using the ledger pattern for future stale closures. |
| #1687 zh-CN localization tail | Translator/manual review | Large safe subsets landed in #1746-#1752; remaining pieces require translator/manual review per salvage ledger. | Do not blindly cherry-pick. Split by docs, commands, agents, and skills if a translator review lane opens. |
| #1687 zh-CN localization tail | Translator/manual review | Large safe subsets landed in #1746-#1752; remaining pieces are attached to Linear ITO-55 for language-owner review. | Do not blindly cherry-pick. Split by docs, commands, agents, and skills if a translator review lane opens; no automatic import remains release-blocking. |
| #1609 Persian README translation | Translator/manual review | Recorded in the stale salvage ledger and attached to Linear ITO-55 for language-owner review. | Do not import stale README/version/count text without a Persian reviewer and a current catalog refresh. |
| #1563 zh-TW README sync | Translator/manual review | Recorded in the stale salvage ledger and attached to Linear ITO-55 for language-owner review. | Do not import stale README/version/count text without a zh-TW reviewer and a current catalog refresh. |
| #1564 Turkish README sync | Translator/manual review | Recorded in the stale salvage ledger and attached to Linear ITO-55 for language-owner review. | Do not import stale README/version/count text without a Turkish reviewer and a current catalog refresh. |
| #1565 pt-BR README sync | Translator/manual review | Recorded in the stale salvage ledger and attached to Linear ITO-55 for language-owner review. | Do not import stale README/version/count text without a pt-BR reviewer and a current catalog refresh. |
## Workspace-Level Legacy Repos
+2 -2
View File
@@ -1,4 +1,4 @@
**Idioma:** [English](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | Português (Brasil) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
**Idioma:** [English](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | Português (Brasil) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
# Everything Claude Code
@@ -24,7 +24,7 @@
**Idioma / Language / 语言 / Dil / Язык / Ngôn ngữ**
[**English**](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Português (Brasil)](README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Português (Brasil)](README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+19 -2
View File
@@ -31,6 +31,10 @@ The leverage comes from treating the harness, reusable workflow layer, and opera
- hooks and verification discipline
- security and review patterns
- operator workflow skills around content, research, and business ops
- queue, discussion, Linear, legacy, and release-evidence checks that make the
operating state inspectable
- supply-chain IOC scanning and no-lifecycle install hardening after the
Mini Shai-Hulud/TanStack campaign
### 3. Why Hermes Is the Operator Layer
@@ -45,8 +49,21 @@ The leverage comes from treating the harness, reusable workflow layer, and opera
- cross-harness architecture doc
- Hermes import guidance
- clearer 2.0 positioning in the repo
- preview-pack smoke gate
- launch drafts for GitHub release copy, X, LinkedIn, article, Telegram/Hermes
handoff, and demo prompts
### 5. What Stays Local
### 5. What Changed Since v1.10.0
- Claude Code remains the core target, but ECC now treats Codex, OpenCode,
Cursor, Gemini, Zed, and terminal-only workflows as shared execution surfaces.
- The release process now has repeatable platform, discussion, observability,
supply-chain, Linear progress, and preview-pack checks.
- AgentShield and ECC Tools work is mirrored into the roadmap so enterprise
security, hosted review, policy promotion, and billing-readiness lanes do not
drift away from the main release.
### 6. What Stays Local
- secrets and auth
- raw workspace exports
@@ -54,7 +71,7 @@ The leverage comes from treating the harness, reusable workflow layer, and opera
- operator-specific automations that have not been sanitized
- deeper CRM, finance, and Google Workspace playbooks
### 6. Closing Point
### 7. Closing Point
The goal is not to copy one exact stack.
+12 -1
View File
@@ -9,7 +9,7 @@ It is becoming a cross-harness operating system for agentic work:
- reusable skills instead of one-off prompts
- hooks and tests instead of manual discipline
- MCP-backed access to docs, code, browser automation, and research
- Codex, OpenCode, Cursor, Gemini, and Claude Code surfaces that share the same core workflow layer
- Codex, OpenCode, Cursor, Gemini, Zed, and Claude Code surfaces that share the same core workflow layer
- Hermes as the operator shell for chat, cron, handoffs, and daily work routing
For this release-candidate surface, I kept the repo honest.
@@ -20,9 +20,20 @@ I did not publish private workspace state. I shipped the reusable layer:
- release notes and launch collateral
- cross-harness architecture notes
- Hermes import guidance for turning local operator patterns into public ECC skills
- release-readiness gates for PRs, issues, discussions, Linear progress, legacy tails, observability, and supply-chain checks
- a deterministic preview-pack smoke test so the public pack can be verified before a release action
The leverage is not just better prompting.
It is reducing the number of isolated surfaces, turning repeated workflows into reusable skills, and making the operating system around the agent measurable.
The supply-chain work became part of the release story too. After the Mini
Shai-Hulud/TanStack campaign, rc.1 now includes IOC scanning, no-lifecycle CI
installs, advisory-source refresh, npm audit/signature checks, and AI-tool
persistence coverage.
There is still more to harden before GA, especially around packaging, installers, and the `ecc2/` control plane. But rc.1 is enough to show the shape clearly.
Public publication is still approval-gated until the GitHub release, npm
`next` publish, plugin path, final URLs, and billing/native-payments claims have
live evidence.
@@ -2,8 +2,8 @@
This dashboard is generated by `npm run operator:dashboard`. It is an operator snapshot, not release approval.
Generated: 2026-05-17T11:40:47.146Z
Commit: 744f4169972fd81618c3114ea1ca5ffb85ef4c82
Generated: 2026-05-17T21:57:47.582Z
Commit: e6c16b40b80b3b323586c9e8341faa87c01a728c
Status: work remaining
## Current Status
@@ -25,31 +25,27 @@ Status: work remaining
| Keep public issues below 20 | scripts/platform-audit.js live GitHub sweep | current | 0 open issues across 5 tracked repos | repeat before release |
| Respond and manage repository discussions | scripts/platform-audit.js discussion summary | current | 0 need maintainer touch; 0 answerable discussions missing accepted answer | repeat before release |
| Build ITO-44 completion dashboard into a repeatable command | npm run operator:dashboard | complete | operator:dashboard package script exists | keep generated dashboard attached to publication evidence |
| ECC 2.0 preview pack ready | docs/releases/2.0.0-rc.1/preview-pack-manifest.md | in_progress | preview pack manifest is in-tree | final clean-checkout release approval and publish evidence still pending |
| Include Hermes specialized skills safely | docs/HERMES-SETUP.md and skills/hermes-imports/SKILL.md | in_progress | Hermes setup and import skill are present | final preview-pack smoke and release review pending |
| ECC 2.0 preview pack ready | docs/releases/2.0.0-rc.1/preview-pack-manifest.md | current | preview pack manifest and deterministic smoke gate are in-tree | repeat clean-checkout preview-pack smoke before publication |
| Include Hermes specialized skills safely | docs/HERMES-SETUP.md and skills/hermes-imports/SKILL.md | current | Hermes setup/import artifacts are covered by preview-pack smoke | repeat preview-pack smoke before release review |
| Prepare name-change, Claude plugin, and Codex plugin paths | naming-and-publication-matrix plus publication-readiness | in_progress | naming matrix and plugin readiness gates exist | real tag/push, marketplace submission, and final channel choice remain approval-gated |
| Prepare release notes, articles, tweets, and push notifications | docs/releases/2.0.0-rc.1 social and release-copy files | in_progress | release notes, X thread, and LinkedIn draft are present | URL-backed refresh and publish approval still pending |
| Advance AgentShield enterprise iteration | AgentShield PR evidence plus enterprise roadmap | in_progress | AgentShield policy promotion `reviewItems` landed in `87aec47`; package-manager hardening drift detection landed in `28d08c7`; workflow action runtime pins were refreshed in `659f569`; npm age-gate guidance was corrected in `ee585cd`; all are mirrored in the GA roadmap | workflow automation still needs to consume promotion review items, package-manager hardening findings, and unsupported npm age-key findings in CI/hosted/runtime smoke surfaces |
| Advance ECC Tools native payments and AI-native harness-agnostic app | ECC Tools PR evidence, billing gate, hosted analysis lanes | in_progress | billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, and harness-route policy linking are mirrored in the GA roadmap | live Marketplace test-account readback, hosted promotion telemetry, and richer operator review UX pending |
| Audit, prune, or attach legacy work | docs/stale-pr-salvage-ledger.md and legacy inventory | in_progress | legacy salvage ledger and ITO-55 tracking are present | final translation/manual-review tail remains |
| Keep Linear roadmap detailed and progress tracking synchronized | Linear project mirror plus progress-sync contract | in_progress | repo mirror and progress-sync contract are present | recurring Linear status sync and productized realtime sync remain pending |
| Advance AgentShield enterprise iteration | AgentShield PR evidence plus enterprise roadmap | in_progress | AgentShield policy promotion `reviewItems` landed in `87aec47`; package-manager hardening drift detection landed in `28d08c7`; workflow action runtime pins were refreshed in `659f569`; npm age-gate guidance was corrected in `ee585cd`; package-manager hardening Action outputs landed in `1124535`; policy-promotion Action outputs and runtime-smoke job-summary evidence landed in `1593925`; ECC-Tools consumes those outputs in `8658951`, surfaces operator-readable status/pack/count/digest telemetry in `16c537f`, and renders hosted promotion judge audit traces in `05d4e82`; all are mirrored in the GA roadmap | deepen live operator approval/readback after Marketplace/payment gates |
| Advance ECC Tools native payments and AI-native harness-agnostic app | ECC Tools PR evidence, billing gate, hosted analysis lanes | in_progress | billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output telemetry, operator-visible promotion output details, hosted promotion judge audit traces, billing announcement preflight, and production KV readback state are mirrored in the GA roadmap | complete Marketplace purchase/webhook readback, then run the live announcement gate |
| Audit, prune, or attach legacy work | docs/stale-pr-salvage-ledger.md and legacy inventory | current | legacy salvage ledger and inventory are current; all localization tails are attached to Linear ITO-55 for manual language-owner review | repeat legacy scan before release |
| Keep Linear roadmap detailed and progress tracking synchronized | Linear project mirror plus progress-sync contract | current | Linear live sync and project progress snapshot are current; progress-sync contract defines the file-backed work-items/status path | repeat Linear/project status update and local work-items sync after each significant merge batch |
| Provide ECC 2.0 observability for self-use | observability readiness gate | complete | observability:ready command and readiness doc exist | runtime/dashboard implementation can continue after release gates |
| Keep Mini Shai-Hulud/TanStack protection loop current | supply-chain watch plus runbook plus AgentShield package-manager hardening | current | scheduled supply-chain watch emits IOC/advisory-source refresh artifacts; AgentShield now detects known AI-tool persistence IOCs, npm lifecycle/token drift, unsupported npm age-key drift, and pnpm/Yarn cooldown drift; ITO-57 has May 17 Linear evidence updates | repeat advisory/source refresh and Linear sync after each significant supply-chain batch |
| Keep Mini Shai-Hulud/TanStack protection loop current | supply-chain watch plus runbook plus AgentShield package-manager hardening | current | scheduled supply-chain watch emits IOC/advisory-source refresh artifacts; ECC scanner covers gh-token-monitor token-store persistence; AgentShield now detects known AI-tool persistence IOCs, npm lifecycle/token drift, unsupported npm age-key drift, and pnpm/Yarn cooldown drift; ITO-57 has May 17 Linear evidence updates | repeat advisory/source refresh and Linear sync after each significant supply-chain batch |
## Top Actions
- `ecc-preview-pack`: final clean-checkout release approval and publish evidence still pending
- `hermes-specialized-skills`: final preview-pack smoke and release review pending
- `naming-and-plugin-publication`: real tag/push, marketplace submission, and final channel choice remain approval-gated
- `release-notes-and-notifications`: URL-backed refresh and publish approval still pending
- `agentshield-enterprise-iteration`: consume policy promotion review items, package-manager hardening findings, and unsupported npm age-key findings in CI/hosted/runtime smoke surfaces
- `ecc-tools-next-level`: live Marketplace test-account readback, hosted promotion telemetry, and richer operator review UX pending
- `legacy-salvage`: final translation/manual-review tail remains
- `linear-roadmap-and-progress`: recurring Linear status sync and productized realtime sync remain pending
- `agentshield-enterprise-iteration`: deepen live operator approval/readback after Marketplace/payment gates
- `ecc-tools-next-level`: complete Marketplace purchase/webhook readback, then run the live announcement gate
## Next Work Order
1. Regenerate this dashboard from the final release commit before publication evidence is recorded.
2. Continue ITO-57 after the next significant supply-chain/advisory-source merge batch.
3. Advance ECC Tools live Marketplace test-account readback before publishing native-payments announcement copy.
2. Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.
3. Complete ECC Tools Marketplace purchase/webhook readback, then run preflight and the live announcement gate before publishing native-payments copy.
4. Resume ITO-45, ITO-46, and ITO-56 only after the generated dashboard and final release gates are refreshed.
@@ -16,13 +16,14 @@ surfaces, or posting announcements.
| `docs/architecture/harness-adapter-compliance.md` | Adapter matrix and scorecard | Verified by `npm run harness:adapters -- --check` |
| `docs/architecture/observability-readiness.md` | Local operator-readiness gate | Verified by `npm run observability:ready` |
| `docs/architecture/progress-sync-contract.md` | GitHub, Linear, handoff, roadmap, and work-item sync boundary | Checked by `node scripts/platform-audit.js --format json --allow-untracked docs/drafts/` |
| `scripts/preview-pack-smoke.js` | Deterministic preview-pack smoke gate | Verified by `npm run preview-pack:smoke` |
| `docs/releases/2.0.0-rc.1/release-notes.md` | GitHub release copy source | Must be refreshed with final live release/package/plugin URLs before publication |
| `docs/releases/2.0.0-rc.1/quickstart.md` | Clone-to-first-workflow path | Covers clone, install, verify, first skill, and harness switch |
| `docs/releases/2.0.0-rc.1/launch-checklist.md` | Operator launch checklist | Must remain approval-gated for release, package, plugin, and announcement actions |
| `docs/releases/2.0.0-rc.1/publication-readiness.md` | Release gate | Requires fresh evidence from the exact release commit |
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md` | Current May 15 queue, roadmap, security, supply-chain watch, no-lifecycle CI install hardening, AgentShield #86 evidence-pack provenance, ECC Tools billing-gate, Actions cache purge, and `ecc2` test evidence through PR #1941 | Must be superseded by a final clean-checkout evidence file before real publication |
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-16.md` | Current May 16/17 queue cleanup, recsys skill merge, GateGuard triage, PR #1947 supply-chain protection, AgentShield #87 plugin-cache confidence evidence, AgentShield #88 evidence-pack inspect/readback, AgentShield #89 evidence-pack fleet routing, AgentShield #90 fleet review items, AgentShield #91 policy export, AgentShield #92 policy promotion, ECC-Tools #76 fleet-summary consumption, ECC-Tools #77 hosted finding evidence paths, ECC-Tools #78 harness policy-route linking, dashboard refresh, and combined Node/Rust/release-surface gate evidence through the May 16 mirror | Must still be repeated from a strict clean checkout before real publication |
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` | Current May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack protection recheck, npm audit/signature checks, operator dashboard refresh, Linear sync, and GitHub CI evidence for `99dd6ac0` | Current strongest readiness snapshot; must still be repeated from a strict clean checkout before real publication |
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` | Current May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack protection recheck, npm audit/signature checks, legacy and Linear progress routing, deterministic preview-pack smoke, operator dashboard refresh, Linear sync, and GitHub CI evidence for `27dc2918` | Current strongest readiness snapshot; must still be repeated from a strict clean checkout before real publication |
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Current prompt-to-artifact operator dashboard | Shows PR/issue/discussion/platform/supply-chain gates current and publication, plugin, billing, AgentShield, ECC Tools, legacy, and Linear productization gaps still open |
| `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` | Naming, slug, and publication-path decision record | Keeps `Everything Claude Code / ECC`, npm `ecc-universal`, and plugin slug `ecc` for rc.1 |
| `docs/releases/2.0.0-rc.1/x-thread.md` | X launch draft | Must replace placeholders with live URLs after release/package/plugin publication |
@@ -69,6 +70,7 @@ Run these from the exact release commit before publication:
```bash
git status --short --branch
node scripts/platform-audit.js --format json --allow-untracked docs/drafts/
npm run preview-pack:smoke
npm run harness:adapters -- --check
npm run harness:audit -- --format json
npm run observability:ready
@@ -7,10 +7,10 @@ npm publication, plugin tag, marketplace submission, or announcement post.
| Field | Evidence |
| --- | --- |
| Upstream main | `744f4169972fd81618c3114ea1ca5ffb85ef4c82` |
| Upstream main | `e6c16b40b80b3b323586c9e8341faa87c01a728c` |
| Git remote | `https://github.com/affaan-m/everything-claude-code.git` |
| Evidence scope | Current `main` after the Japanese localization and Dependabot merge batch, post-merge ja-JP markdown anchor repair, Zed install-target support, Mini Shai-Hulud/TanStack protection recheck, and the Windows-path CI fix |
| Local status caveat | `git status --short --branch` showed `## main...origin/main` plus unrelated untracked `docs/drafts/` |
| Evidence scope | Current `main` after the Japanese and Thai localization merge batch, post-merge ja-JP markdown anchor repair, Zed install-target support, Mini Shai-Hulud/TanStack protection recheck, `gh-token-monitor` token-store IOC coverage, AgentShield policy-promotion Action output mirror, ECC-Tools hosted promotion judge audit-trace mirror, ECC-Tools billing announcement preflight mirror, ECC-Tools production Marketplace readback-state mirror, legacy-tail dashboard routing, Linear progress readiness, and the deterministic preview-pack smoke gate |
| Local status caveat | `git status --short --branch` showed `## main...origin/main` plus unrelated untracked `docs/drafts/`; generated evidence files are committed after the source snapshot they describe |
The actual release operator should repeat all publish-facing checks from the
final release commit with a strictly clean checkout before publishing.
@@ -22,7 +22,7 @@ final release commit with a strictly clean checkout before publishing.
| Trunk PRs | `gh pr list --state open --limit 50 --json number,title` | 0 open PRs |
| Trunk issues | `gh issue list --state open --limit 50 --json number,title` | 0 open issues |
| Platform audit | `node scripts/platform-audit.js --json --allow-untracked docs/drafts/` | Ready; tracked repos report 0 open PRs, 0 open issues, 0 discussion maintainer-touch gaps, 0 answerable Q&A missing accepted answers, and 0 blocking dirty files |
| Operator dashboard | `npm run operator:dashboard -- --allow-untracked docs/drafts/ --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Generated current dashboard for `744f4169972fd81618c3114ea1ca5ffb85ef4c82`; status remains `work remaining` because release, npm, plugin, billing, and announcement gates are approval-gated |
| Operator dashboard | `npm run operator:dashboard -- --markdown --allow-untracked docs/drafts/ --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Generated current dashboard for `e6c16b40b80b3b323586c9e8341faa87c01a728c`; dashboard ready true, publication ready false because release, npm, plugin, billing, and announcement gates are approval-gated |
Tracked repositories in the platform audit were:
@@ -47,22 +47,43 @@ Tracked repositories in the platform audit were:
| Zed adapter commit | Pushed `2371a3cf0543365c1c18e84eba786b1abcb28941` to add project-local Zed support through the selective install target, README Zed guidance, and `.zed/settings.json` planning coverage |
| Zed Windows CI fix | Pushed `744f4169972fd81618c3114ea1ca5ffb85ef4c82` to normalize the Zed install-plan source-path assertion across Windows path separators |
| Discussion #1896 | Added a maintainer update confirming Zed support on `main`, documenting the dry-run command, and clarifying that BYOK/OpenRouter secrets stay in Zed/local user settings rather than ECC-managed project files |
| PR #1967 | Merged Thai localization as `6b282aaa4389e9411e86bfe09d8f4de8018dcf8e` after applying the two maintainer cleanup comments, validating markdownlint and language-switcher coverage, and approving after CodeRabbit, GitGuardian, Greptile, and cubic passed on current head |
| Supply-chain token-store scanner slice | Pushed `36d390aa7d733d458963a203b91998d3aec477b2` to detect the Mini Shai-Hulud `~/.config/gh-token-monitor/token` dead-man-switch token store, update the incident-response runbook, and add fixture coverage; local sweeps stayed clean and GitHub Actions `26003629550` passed |
| Legacy-tail dashboard slice | Pushed `f397216aee5a0ca7d168726d3cc41eb47f728b37` and dashboard regeneration commits to keep localization-tail evidence attached to ITO-55 and prevent stale legacy work from being treated as release-current |
| Linear progress readiness slice | Pushed `355c4f128183aa7f7ce9da9485af07d257d67f69` and dashboard regeneration commit `1a384dc5dbd24a3be725e1b26c169bddb6c850b6` to require refreshed Linear progress evidence after significant merge batches |
| Preview-pack smoke slice | Pushed `3215e655eff70b9fea5382ce5996666a1f48d1af` to add `npm run preview-pack:smoke`, covering preview-pack artifacts, Hermes import boundaries, verification commands, and approval-gated publication blockers; lint and dashboard follow-up commits landed through `27dc2918a24a50b8dd5e23dba2aa6a05bd17c0d7` |
| AgentShield hardening-output slice | Pushed AgentShield `1124535345d7040242ecd3803f65bcd4dcaf6ec2` to expose package-manager hardening status/count outputs and redacted GitHub Action job-summary evidence for registry credentials, lifecycle-script drift, and release-age gate drift |
| AgentShield policy-promotion Action slice | Pushed AgentShield `1593925dca025632dd8a6454509fce3fe7517cdf` to expose policy-promotion status/count/digest outputs plus GitHub Action job-summary review items for owner approval, protected rollout, and runtime smoke; the same Action job marks runtime smoke verified when it scans with the promoted policy |
| ECC-Tools policy-promotion telemetry slice | Pushed ECC-Tools `86589517b11b95f1b0216ae7737563fb67ee1604` to route AgentShield policy-promotion Action outputs into hosted security review findings and Hosted Promotion Readiness scoring |
| ECC-Tools policy-promotion operator UX slice | Pushed ECC-Tools `16c537fd385458c438ff32fb4211079b2f8ea1c4` to render policy-promotion Action output status, pack, review item count, remaining action count, and digest in hosted security job comments and check-runs |
| ECC-Tools hosted promotion judge audit trace slice | Pushed ECC-Tools `05d4e8296e37ba72e471beaa23ea4c81eb2aa31f` to render hosted promotion judge request fingerprints and allowed-citation audit traces without exposing raw provider output |
| ECC-Tools billing announcement preflight slice | Pushed ECC-Tools `91a441b92342b842832ac28b018ee46f0c4a906f` to add `npm run billing:announcement-gate -- --preflight` for safe Marketplace readback input and endpoint verification before privileged API calls |
| ECC-Tools production Marketplace readback-state slice | Pushed ECC-Tools `eb6941290b2fa70db01a51084e9e79a160238468` to record that production Cloudflare secret names include `INTERNAL_API_SECRET`, but production KV currently has no `account-billing:*` or `billing-state:*` records |
## Release Gate Commands
| Gate | Command | Result |
| --- | --- | --- |
| Root lint | `npm run lint` | Passed after the ja-JP autonomous-loop anchor repair |
| Root suite | `npm test` | 2479 passed, 0 failed |
| Root suite | `npm test` | 2487 passed, 0 failed |
| GitHub Actions CI | `gh run view 25989533576 --json status,conclusion,jobs` | Completed successfully with 37/37 jobs green, including Security Scan and all Windows test jobs |
| Harness audit | `node scripts/harness-audit.js --format json` | 70/70, no top actions |
| Observability readiness | `npm run observability:ready -- --format json` | 21/21, ready yes |
| Workflow security | `node scripts/ci/validate-workflow-security.js` | Validated 8 workflow files |
| Supply-chain IOC scan | `node scripts/ci/scan-supply-chain-iocs.js --home` | Passed; 200 files inspected, including user-level persistence targets |
| Supply-chain IOC scan | `node scripts/ci/scan-supply-chain-iocs.js --root ~/GitHub --home --json`; `node scripts/ci/scan-supply-chain-iocs.js --root ~/Documents/GitHub --home --json` | Passed; each workspace sweep inspected 1,879 files with 0 findings, including user-level persistence targets |
| npm audit | `npm audit --audit-level=high` | 0 vulnerabilities |
| npm signatures | `npm audit signatures` | 213 verified registry signatures; 17 verified attestations |
| GitHub queues | `gh pr list`; `gh issue list`; `node scripts/platform-audit.js --json --allow-untracked docs/drafts/` | 0 open PRs, 0 open issues, and platform audit ready across the tracked repo set |
| Operator dashboard | `npm run operator:dashboard -- --allow-untracked docs/drafts/ --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Dashboard generated for the current commit; macro publication gates still incomplete |
| npm signatures | `npm audit signatures` across `agentshield`, `everything-claude-code`, `ECC-Tools`, `ECC-website`, and `JARVIS/frontend` | Passed across the primary ECC Node package roots |
| Preview-pack smoke | `npm run preview-pack:smoke` | Passed; ready yes; digest `dfb1ed014607`; 5 checks passed and 0 failed |
| AgentShield enterprise CI output slice | AgentShield local `npm run build`, focused action tests, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25994354007`, `25994354011`, `25994354026` | Local gates passed; remote CI, Test GitHub Action, and Self-Scan completed successfully for `1124535` |
| AgentShield policy-promotion Action output slice | AgentShield local `npm run build`, `npx vitest run tests/action-promotion.test.ts tests/action.test.ts`, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25995929182`, `25995929190`, `25995929161` | Local gates passed; remote CI, Test GitHub Action, and Self-Scan completed successfully for `1593925` |
| ECC-Tools policy-promotion hosted telemetry slice | ECC-Tools local focused vitest checks for policy-promotion Action-output routing and hosted-promotion readiness, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25996758218` | Local gates passed; remote CI completed successfully for `8658951` |
| ECC-Tools policy-promotion operator UX slice | ECC-Tools local focused vitest checks for policy-promotion Action output values in hosted findings/comments/checks, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25997300046` | Local gates passed; remote CI completed successfully for `16c537f` |
| ECC-Tools hosted promotion judge audit trace slice | ECC-Tools local focused vitest checks for hosted model-judge audit traces, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25997840703` | Local gates passed; remote CI completed successfully for `05d4e82` |
| ECC-Tools billing announcement preflight slice | ECC-Tools local focused vitest preflight tests, `npm run typecheck`, `npm run lint`, full `npm test`, and `git diff --check`; GitHub Actions `25998238507` | Local gates passed; remote CI completed successfully for `91a441b` |
| ECC-Tools production Marketplace readback-state slice | ECC-Tools local `npm test` and `git diff --check`; Cloudflare `wrangler secret list` confirmed `INTERNAL_API_SECRET` exists by name; `wrangler kv key list` for `account-billing:` and `billing-state:` both returned empty lists; GitHub Actions `25998610438` | Local gates passed; remote CI completed successfully for `eb69412`; live announcement remains blocked until Marketplace purchase/webhook records populate KV |
| GitHub queues | `gh pr list`; `gh issue list`; `node scripts/platform-audit.js --json --allow-untracked docs/drafts/` | 0 open PRs, 0 open issues, 0 discussion maintainer-touch gaps, 0 answerable Q&A missing accepted answers, 0 GitHub fetch errors, and platform audit ready across the tracked repo set after generated evidence is committed |
| Operator dashboard | `npm run operator:dashboard -- --markdown --allow-untracked docs/drafts/ --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Dashboard generated for `e6c16b40b80b3b323586c9e8341faa87c01a728c` with platform ready true, dashboard ready true, and macro publication gates still incomplete |
| GitHub Actions CI | `gh run watch 26003629550 --repo affaan-m/everything-claude-code --exit-status` | Completed successfully for `36d390aa7d733d458963a203b91998d3aec477b2`, including Validate Components, Lint, Security Scan, Coverage, and the full OS/Node/package-manager matrix |
## Current Publication Blockers
@@ -73,8 +94,10 @@ Tracked repositories in the platform audit were:
- Codex repo-marketplace distribution is verified for rc.1, but official
Plugin Directory publishing remains blocked on OpenAI's self-serve publishing
surface.
- ECC Tools billing/native-payments copy remains blocked until live
Marketplace-managed test-account readback returns an announcement-ready gate.
- ECC Tools billing/native-payments copy remains blocked until a Marketplace
purchase/webhook path writes production `account-billing:*` and
`billing-state:*` records, then `npm run billing:announcement-gate --
--account <github-login>` returns an announcement-ready gate.
- Release notes, X, LinkedIn, GitHub release, and longform copy still need final
live URLs after release/package/plugin URLs exist.
- The local checkout still has unrelated untracked `docs/drafts/`, so a strict
@@ -31,7 +31,8 @@ combined final-gate rerun on current `main`, see
[`publication-evidence-2026-05-16.md`](publication-evidence-2026-05-16.md).
For the May 17 queue cleanup, Japanese localization merge, Dependabot
TypeScript and Node type merges, post-merge ja-JP lint repair, Mini
Shai-Hulud/TanStack local protection recheck, and current operator dashboard
Shai-Hulud/TanStack local protection recheck, legacy-tail and Linear progress
routing, deterministic preview-pack smoke gate, and current operator dashboard
refresh, see
[`publication-evidence-2026-05-17.md`](publication-evidence-2026-05-17.md).
For the operator-facing prompt-to-artifact readiness dashboard from the same
@@ -78,12 +79,13 @@ Record the exact commit SHA and command output before any publication action:
| Evidence | Command | Required result | Recorded output |
| --- | --- | --- | --- |
| Clean release branch | `git status --short --branch` | On intended release commit; no unrelated files | Pending final strict clean-checkout release pass; `publication-evidence-2026-05-17.md` records current `main` with unrelated untracked `docs/drafts/` |
| Preview-pack smoke | `npm run preview-pack:smoke` | Preview pack artifacts, Hermes boundary, final verification command list, and publication blockers pass | `publication-evidence-2026-05-17.md`: ready yes, digest `dfb1ed014607`, 5 passed, 0 failed; repeat in a final strict clean-checkout release pass |
| Harness audit | `npm run harness:audit -- --format json` | 70/70 passing | `publication-evidence-2026-05-17.md`: 70/70 |
| Adapter scorecard | `npm run harness:adapters -- --check` | PASS | `publication-evidence-2026-05-16.md`: PASS, 11 adapters |
| Observability readiness | `npm run observability:ready` | 21/21 passing | `publication-evidence-2026-05-17.md`: 21/21, ready yes |
| Release safety gate | `npm run observability:ready -- --format json` | Release Safety category passing with publication readiness, supply-chain, workflow security, package surface, and release-surface evidence | `publication-evidence-2026-05-13-post-hardening.md`: Release Safety 3/3 |
| Supply-chain verification | `npm audit --json`; `npm audit signatures`; `cd ecc2 && cargo audit -q`; Dependabot alerts; GitGuardian Security Checks | 0 vulnerabilities/alerts, registry signatures verified, GitGuardian clean | `publication-evidence-2026-05-17.md`: npm registry signatures and attestations verified, 0 high-or-higher npm vulnerabilities, supply-chain IOC scan clean |
| Root suite | `node tests/run-all.js` | 0 failures | `publication-evidence-2026-05-17.md`: `npm test` passed 2473/2473, 0 failed |
| Root suite | `node tests/run-all.js` | 0 failures | `publication-evidence-2026-05-17.md`: `npm test` passed 2487/2487, 0 failed |
| Markdown lint | `npx markdownlint-cli '**/*.md' --ignore node_modules` | 0 failures | `publication-evidence-2026-05-17.md`: passed after ja-JP autonomous-loop anchor repair |
| Package surface | `node tests/scripts/npm-publish-surface.test.js` | 0 failures; no Python bytecode in npm tarball | `2/2` passed in May 12 evidence pass |
| Release surface | `node tests/docs/ecc2-release-surface.test.js` | 0 failures | `publication-evidence-2026-05-16.md`: 20/20 passed |
@@ -91,7 +93,7 @@ Record the exact commit SHA and command output before any publication action:
| Queue baseline | `gh pr list` / `gh issue list` across trunk, AgentShield, JARVIS, ECC Tools, and ECC website | Under 20 open PRs and under 20 open issues | `publication-evidence-2026-05-17.md`: platform audit ready, 0 open PRs and 0 open issues across checked repos |
| Discussion baseline | `node scripts/discussion-audit.js --json` | No unmanaged active discussion queue and no answerable Q&A missing an accepted answer | `publication-evidence-2026-05-15.md`: 58 trunk discussions, 0 without maintainer touch; other tracked repos disabled or 0 |
| Linear roadmap | Linear project and issue readback | Detailed roadmap exists with release, security, AgentShield, ECC Tools, legacy, and observability lanes | `publication-evidence-2026-05-15.md`: project and 16 issue lanes recorded |
| Operator readiness dashboard | `npm run operator:dashboard -- --allow-untracked docs/drafts/ --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Current queue state mapped to macro-goal deliverables and incomplete gaps | `operator-readiness-dashboard-2026-05-17.md`: regenerated from `afe0ae8d`, 0 open PRs, 0 open issues, 0 discussion gaps |
| Operator readiness dashboard | `npm run operator:dashboard -- --json --allow-untracked docs/drafts/` | Current queue state mapped to macro-goal deliverables and incomplete gaps | `publication-evidence-2026-05-17.md`: generated from `27dc2918`, platform ready true, dashboard ready true, 0 open PRs, 0 open issues, 0 discussion gaps |
## Do Not Publish If
+37
View File
@@ -13,9 +13,38 @@ Claude Code remains a core target. Codex, OpenCode, Cursor, Gemini, and other ha
- Clarified the split between ECC as the reusable substrate and Hermes as the operator shell.
- Documented the cross-harness portability model for skills, hooks, MCPs, rules, and instructions.
- Added a Hermes import playbook for turning local operator patterns into publishable ECC skills.
- Added Zed as a project-local planning/install target while keeping BYOK and OpenRouter secrets outside ECC-managed project files.
- Added command-registry coverage, platform audit, discussion audit, operator dashboard, Linear progress readiness, and preview-pack smoke gates.
- Added a local [observability readiness gate](../../architecture/observability-readiness.md) for loop status, session traces, harness audit, and ECC2 tool-risk logs.
- Refreshed the release-readiness evidence after the May 2026 Mini Shai-Hulud/TanStack campaign follow-up, including full-campaign AgentShield IOC coverage, queue-zero/discussion checks, a detailed Linear roadmap gate, and the May 17 operator dashboard snapshot.
## Since v1.10.0
The rc.1 surface now includes the main 2.0 direction rather than one isolated
feature branch:
- cross-harness substrate work for Claude Code, Codex, OpenCode, Cursor,
Gemini, Zed, and terminal-only workflows;
- stronger package and plugin publication surfaces for npm, Claude plugin,
Codex repo-marketplace, OpenCode, and agent metadata;
- operator gates for PRs, issues, discussions, stale legacy work, Linear
progress, release evidence, and dashboard repeatability;
- supply-chain hardening after the Mini Shai-Hulud/TanStack campaign,
including IOC scanning, no-lifecycle CI installs, advisory-source refresh,
npm audit/signature checks, and user-level AI-tool persistence targets;
- AgentShield enterprise-roadmap mirrors for package-manager hardening,
evidence-pack provenance, policy export, policy promotion, fleet routing,
and GitHub Action output telemetry;
- ECC Tools roadmap mirrors for hosted analysis, fleet-summary consumption,
finding evidence paths, harness policy-route linking, hosted promotion judge
audit traces, billing announcement preflight, and production Marketplace
readback state;
- documentation expansion, Japanese localization, zh-CN to ja-JP parity
repair, and dependency readiness through TypeScript 6 and Node type updates;
- launch collateral for GitHub release copy, X, LinkedIn, article outline,
Telegram/Hermes handoff, demo prompts, and the approval-gated launch
checklist.
## Why This Matters
ECC is no longer only a Claude Code plugin or config bundle.
@@ -39,6 +68,7 @@ What ships in this surface:
- cross-harness architecture documentation
- Hermes import guidance for sanitized operator workflows
- publication-readiness evidence for queue state, discussion state, Linear roadmap coverage, operator dashboard status, and supply-chain follow-up
- preview-pack smoke evidence proving the public pack is assembled without private Hermes state
What stays local:
@@ -57,3 +87,10 @@ What stays local:
5. Start with one workflow lane: engineering, research, content, or outreach.
6. Import only sanitized operator patterns into ECC skills.
7. Treat `ecc2/` as an alpha control plane until release packaging and installer behavior are finalized.
## Do Not Treat This As Published Yet
The release candidate copy is ready for final review, but the public release is
still blocked on approval-gated actions: the GitHub prerelease, npm `next`
publish, Claude plugin tag/marketplace path, Codex Plugin Directory status,
final live URLs, and any billing or native-payments announcement.
+5 -1
View File
@@ -10,6 +10,9 @@ Use the public ECC release pack in the repo:
- docs/releases/2.0.0-rc.1/linkedin-post.md
- docs/releases/2.0.0-rc.1/article-outline.md
- docs/releases/2.0.0-rc.1/launch-checklist.md
- docs/releases/2.0.0-rc.1/preview-pack-manifest.md
- docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md
- docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md
- docs/HERMES-SETUP.md
- docs/architecture/cross-harness.md
@@ -20,7 +23,8 @@ Task:
3. Give me one 30-60 second Hermes x ECC video script and one 15-30 second variant.
4. Tell me exactly what to record now with screen capture, face camera, and voice lines.
5. Tell me what Hermes can generate automatically after I record.
6. End with a minimal checklist of the assets or logins still needed.
6. Keep every public claim release-candidate framed until live release/npm/plugin URLs exist.
7. End with a minimal checklist of the assets or logins still needed.
Be decisive. Return final drafts plus a practical recording checklist.
```
+24 -9
View File
@@ -17,16 +17,31 @@ Codex, OpenCode, Cursor, Gemini, and other harnesses are part of the same story
The goal is fewer one-off harness tricks and more reusable workflow surface.
4/ The rc.1 surface ships the public pieces:
4/ Since v1.10.0, the work also picked up the operator layer:
PR/issue/discussion audits, Linear progress sync, release evidence, observability checks, and a generated readiness dashboard.
5/ The security posture changed too.
The Mini Shai-Hulud/TanStack campaign forced a real supply-chain loop:
- IOC scanning
- no-lifecycle CI installs
- advisory-source refresh
- npm audit/signature checks
- AI-tool persistence targets
6/ The rc.1 surface ships the public pieces:
- Hermes setup guide
- release notes
- launch checklist
- X and LinkedIn drafts
- cross-harness architecture doc
- Hermes import guidance
- preview-pack smoke gate
- X, LinkedIn, and article drafts
5/ It does not ship private workspace state.
7/ It does not ship private workspace state.
No secrets.
No OAuth tokens.
@@ -35,25 +50,25 @@ No personal datasets.
The point is to publish the reusable system shape.
6/ Why Hermes matters:
8/ Why Hermes matters:
Most agent systems fail in the daily operating loop.
They can code, but they do not keep research, content, handoffs, reminders, and execution in one measurable surface.
7/ ECC gives the reusable layer.
9/ ECC gives the reusable layer.
Hermes gives the operator shell.
Together they make the work feel less like scattered chat windows and more like a system you can run.
8/ This is still a release candidate.
10/ This is still a release candidate.
The public docs and reusable surfaces are ready for review.
The deeper local integrations stay local until they are sanitized.
The deeper local integrations stay local until they are sanitized, and publication still waits on the GitHub release, npm, plugin, and final URL gates.
9/ Start here:
11/ Start here:
Repo:
<https://github.com/affaan-m/everything-claude-code>
@@ -61,5 +76,5 @@ Repo:
Hermes x ECC setup:
<https://github.com/affaan-m/everything-claude-code/blob/main/docs/HERMES-SETUP.md>
Release notes:
12/ Release notes:
<https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-notes.md>
+2 -2
View File
@@ -1,4 +1,4 @@
**Язык:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md)
**Язык:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
# Everything Claude Code
@@ -27,7 +27,7 @@
**Язык / 语言 / 語言 / Dil / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
@@ -27,8 +27,8 @@ credentials:
they carried destructive or unauthorized file-writing behavior.
- The live IOC set includes persistence through Claude Code
`.claude/settings.json`, VS Code `.vscode/tasks.json`, and OS-level
`gh-token-monitor` LaunchAgent/systemd services. Some variants add a
dead-man-switch token description
`gh-token-monitor` LaunchAgent/systemd services. Some variants add
`~/.config/gh-token-monitor/token` plus a dead-man-switch token description
`IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner`, malicious workflow
files such as `.github/workflows/codeql_analysis.yml`, and Python runtime
payloads such as `transformers.pyz` / `pgmonitor.py`. Remove those
@@ -124,6 +124,7 @@ If ECC or a maintainer machine installed a known-bad package version:
- `~/Library/LaunchAgents/com.user.gh-token-monitor.plist`;
- `~/.config/systemd/user/gh-token-monitor.service`;
- `~/.config/systemd/user/pgsql-monitor.service`;
- `~/.config/gh-token-monitor/token`;
- `~/.local/bin/gh-token-monitor.sh`;
- `~/.local/bin/pgmonitor.py`;
- `/tmp/transformers.pyz`, `/tmp/pgmonitor.py`, and their
+3 -1
View File
@@ -122,7 +122,9 @@ porting.
## Remaining Manual-Review Backlog
The remaining plausibly useful backlog is translation/localization work that is
unsafe to auto-port without language-owner review:
unsafe to auto-port without language-owner review. This tail is attached to
Linear ITO-55 and is not a release-blocking salvage task; release work should
only verify that the backlog remains recorded and excluded from blind imports:
- #1687 zh-CN localization tail
- #1609 Persian README translation
+263
View File
@@ -0,0 +1,263 @@
**ภาษา:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย**
# Everything Claude Code
![Everything Claude Code — ระบบเพิ่มประสิทธิภาพสำหรับ AI agent harness](../../assets/hero.png)
[![Stars](https://img.shields.io/github/stars/affaan-m/everything-claude-code?style=flat)](https://github.com/affaan-m/everything-claude-code/stargazers)
[![Forks](https://img.shields.io/github/forks/affaan-m/everything-claude-code?style=flat)](https://github.com/affaan-m/everything-claude-code/network/members)
[![Contributors](https://img.shields.io/github/contributors/affaan-m/everything-claude-code?style=flat)](https://github.com/affaan-m/everything-claude-code/graphs/contributors)
[![npm ecc-universal](https://img.shields.io/npm/dw/ecc-universal?label=ecc-universal%20weekly%20downloads&logo=npm)](https://www.npmjs.com/package/ecc-universal)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
> **182K+ ดาว** | **28K+ fork** | **170+ คอนทริบิวเตอร์** | **12+ ระบบนิเวศภาษาโปรแกรม** | **ผู้ชนะ Anthropic Hackathon**
---
<div align="center">
**ภาษา / Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ**
[English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย**
</div>
---
**Everything Claude Code (ECC) คือระบบเพิ่มประสิทธิภาพสำหรับ AI agent harness จากผู้ชนะ Anthropic Hackathon**
ECC ไม่ใช่แค่ชุดไฟล์คอนฟิก แต่เป็นระบบครบวงจร: skills, สัญชาตญาณ (instincts), การจัดการหน่วยความจำ (memory optimization), การเรียนรู้ต่อเนื่อง (continuous learning), การสแกนความปลอดภัย (security scanning) และการพัฒนาที่ตรวจสอบจากแหล่งข้อมูลจริง (research-first development) ทั้งหมดนี้ผ่านการใช้งานจริงมากกว่า 10 เดือนในการสร้างผลิตภัณฑ์จริง
ใช้งานได้ข้าม **Claude Code**, **Codex**, **Cursor**, **OpenCode**, **Gemini**, **Zed**, **GitHub Copilot** และ AI agent harness อื่น ๆ
หน้านี้คือคู่มือเริ่มต้นใช้งานฉบับย่อภาษาไทย สำหรับเนื้อหาเต็มและล่าสุดเสมอ ให้อ้างอิงจาก [README ภาษาอังกฤษ](../../README.md) เป็นหลัก
---
## เริ่มต้นใช้งานอย่างเร็ว
### เลือกวิธีติดตั้งเพียงวิธีเดียว
สำหรับผู้ใช้ Claude Code ส่วนใหญ่ ควรเลือก **เพียงหนึ่ง** ในสองวิธีต่อไปนี้:
- **แนะนำ:** ติดตั้งผ่าน Claude Code plugin จากนั้นค่อยคัดลอกเฉพาะโฟลเดอร์ `rules/` ที่ต้องการใช้จริงด้วยมือ
- **ใช้ installer แบบ manual** หากต้องการควบคุมรายละเอียดมากขึ้น หรือต้องการเลี่ยง plugin หรือ Claude Code ของคุณไม่สามารถ resolve marketplace ที่ self-host ได้
- **อย่าติดตั้งซ้อนกันหลายวิธี** ปัญหาที่พบบ่อยที่สุดคือการรัน `/plugin install` ก่อน แล้วตามด้วย `install.sh --profile full` หรือ `npx ecc-install --profile full`
หากคุณติดตั้งซ้อนกันไปแล้วและพบว่ามี skill/hook ซ้ำ ดู [Reset / ถอนการติดตั้ง ECC](#reset--ถอนการติดตั้ง-ecc)
### ติดตั้งผ่าน Claude Code plugin
```bash
# เพิ่ม marketplace
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
# ติดตั้ง plugin
/plugin install ecc@ecc
```
ECC มีชื่อเรียกในระบบสาธารณะ 3 ชื่อที่ต่างกัน:
- GitHub repo: `affaan-m/everything-claude-code`
- Claude marketplace plugin: `ecc@ecc`
- npm package: `ecc-universal`
ชื่อเหล่านี้ตั้งใจให้ต่างกัน Plugin บน Claude Code ใช้ `ecc@ecc` ส่วน npm ยังคงใช้ `ecc-universal`
### คัดลอกไฟล์ rules เพิ่มเติม (ถ้าต้องการ)
Plugin ของ Claude Code จะไม่ติดตั้ง `rules/` ให้อัตโนมัติ หากคุณติดตั้งผ่าน plugin **อย่า** รัน full installer เพิ่ม ให้คัดลอกเฉพาะชุด rule ที่ต้องการแทน:
```bash
git clone https://github.com/affaan-m/everything-claude-code.git
cd everything-claude-code
mkdir -p ~/.claude/rules/ecc
cp -R rules/common ~/.claude/rules/ecc/
cp -R rules/typescript ~/.claude/rules/ecc/
```
```powershell
git clone https://github.com/affaan-m/everything-claude-code.git
cd everything-claude-code
New-Item -ItemType Directory -Force -Path "$HOME/.claude/rules/ecc" | Out-Null
Copy-Item -Recurse rules/common "$HOME/.claude/rules/ecc/"
Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/ecc/"
```
ให้คัดลอกทั้งโฟลเดอร์ภาษา เช่น `rules/common` หรือ `rules/golang` แทนการคัดลอกไฟล์เดี่ยว ๆ
### ติดตั้งแบบ manual (ไม่ใช้ plugin)
ใช้วิธีนี้เฉพาะเมื่อคุณตั้งใจไม่ใช้ plugin:
```bash
npm install
./install.sh --profile full
```
```powershell
npm install
.\install.ps1 --profile full
# หรือ
npx ecc-install --profile full
```
หากเลือกวิธี manual แล้ว ให้หยุดที่นี่ อย่ารัน `/plugin install` เพิ่ม
### แบบ low-context / ไม่มี hooks
หากต้องการเฉพาะ rules, agents, commands และ core workflow skills ให้ใช้ profile แบบมินิมัล:
```bash
./install.sh --profile minimal --target claude
```
```powershell
.\install.ps1 --profile minimal --target claude
# หรือ
npx ecc-install --profile minimal --target claude
```
Profile นี้จงใจไม่ติดตั้ง `hooks-runtime`
---
## Reset / ถอนการติดตั้ง ECC
หาก ECC ติดตั้งซ้อนกัน รบกวนระบบ หรือทำงานผิดปกติ อย่ารันติดตั้งทับซ้ำเข้าไปอีก
- **วิธี plugin:** ถอน plugin ออกจาก Claude Code จากนั้นลบโฟลเดอร์ rule ที่คุณคัดลอกเองใน `~/.claude/rules/ecc/`
- **วิธี installer/CLI:** ที่ root ของ repo ตรวจดูก่อน:
```bash
node scripts/uninstall.js --dry-run
```
จากนั้นถอนไฟล์ที่ ECC ดูแล:
```bash
node scripts/uninstall.js
```
หรือใช้ lifecycle wrapper:
```bash
node scripts/ecc.js list-installed
node scripts/ecc.js doctor
node scripts/ecc.js repair
node scripts/ecc.js uninstall --dry-run
```
ECC จะลบเฉพาะไฟล์ที่อยู่ใน install-state ของตัวเอง ไม่แตะไฟล์อื่นนอกเหนือจากนั้น
---
## คู่มือหลัก
ที่นี่เป็นเพียงโค้ดต้นฉบับ คู่มือเหล่านี้อธิบายรายละเอียดแบบเต็ม:
| คู่มือ | สิ่งที่คุณจะได้เรียนรู้ |
|--------|-------------------------|
| **Shorthand Guide** | การติดตั้ง พื้นฐาน และปรัชญา — อ่านก่อน |
| **Longform Guide** | การประหยัด token, การคงสภาพ memory, evals, การทำงานแบบขนาน |
| **Security Guide** | ช่องโหว่ของ agent, sandboxing, sanitization, CVE, AgentShield |
| หัวข้อ | สิ่งที่คุณจะได้เรียนรู้ |
|-------|-------------------------|
| Token Optimization | การเลือกโมเดล, การลดขนาด system prompt, background processes |
| Memory Persistence | Hooks ที่บันทึก/โหลด context ข้าม session อัตโนมัติ |
| Continuous Learning | ดึง pattern จาก session เป็น skill ใหม่อัตโนมัติ |
| Verification Loops | Checkpoint vs continuous evals, ประเภท grader, ตัววัด pass@k |
| Parallelization | Git worktrees, cascade method, จังหวะการ scale instance |
| Subagent Orchestration | ปัญหา context, pattern การ retrieve แบบทำซ้ำ |
---
## เอกสารสำคัญ
- [README ภาษาอังกฤษ](../../README.md) — แหล่งข้อมูลหลักที่อัปเดตล่าสุดเสมอ
- [คู่มือติดตั้ง Hermes](../HERMES-SETUP.md)
- [Release notes v2.0.0-rc.1](../releases/2.0.0-rc.1/release-notes.md)
- [สถาปัตยกรรม cross-harness](../architecture/cross-harness.md)
- [Troubleshooting](../TROUBLESHOOTING.md)
- [Hook bug workarounds](../hook-bug-workarounds.md)
- [คู่มือการพัฒนา skill](../SKILL-DEVELOPMENT-GUIDE.md)
---
## ลองใช้งาน
```bash
# ติดตั้งผ่าน plugin ใช้ namespace เต็ม
/ecc:plan "เพิ่มระบบยืนยันตัวตนผู้ใช้"
# ติดตั้งแบบ manual ใช้ slash command แบบสั้นได้
# /plan "เพิ่มระบบยืนยันตัวตนผู้ใช้"
# ดู plugin ที่ติดตั้งอยู่
/plugin list ecc@ecc
```
คำสั่งหลักที่ใช้บ่อย:
- `/tdd` — workflow แบบ Test-Driven Development
- `/plan` — วางแผนการ implement
- `/e2e` — สร้างและรัน E2E tests
- `/code-review` — ตรวจคุณภาพโค้ด
- `/build-fix` — แก้ปัญหา build
- `/learn` — ดึง pattern จาก session
- `/skill-create` — สร้าง skill จาก git history
ปัจจุบัน ECC มี agent หลายสิบตัว, skill มากกว่า 200 ชุด และ legacy command shim สำหรับ workflow ต่าง ๆ ดูรายการเต็มและคำแนะนำล่าสุดได้ใน [README ภาษาอังกฤษ](../../README.md)
---
## ร่วมพัฒนาโปรเจกต์
ยินดีต้อนรับการ contribute! สำหรับคู่มือฉบับเต็ม โปรดดู [CONTRIBUTING.md](../../CONTRIBUTING.md)
หมวดที่กำลังต้องการการ contribute:
- **Agents** — agent เฉพาะภาษา (Python, Go, Rust), เฉพาะ framework (Django, Rails, Laravel, Spring), DevOps (Kubernetes, Terraform), domain expert (ML, data engineering, mobile)
- **Skills** — แนวปฏิบัติเฉพาะภาษา, pattern ของ framework, กลยุทธ์การทดสอบ, คู่มือสถาปัตยกรรม
- **Hooks** — automation, linting, security checks, validation, notification
- **Commands** — slash command สำหรับ deployment, testing, code generation
- **คำแปลภาษาอื่น ๆ** — ดูโครงสร้างใน `docs/` (เช่น `docs/zh-CN`, `docs/ja-JP`, `docs/th`)
### ขั้นตอนเริ่มต้นอย่างย่อ
```bash
# 1. Fork และ clone
gh repo fork affaan-m/everything-claude-code --clone
cd everything-claude-code
# 2. สร้าง branch
git checkout -b feat/my-contribution
# 3. เพิ่มสิ่งที่ contribute (ดู CONTRIBUTING.md)
# 4. ทดสอบในเครื่อง
cp -r skills/my-skill ~/.claude/skills/
# 5. ส่ง PR
git add . && git commit -m "feat: add my-skill" && git push -u origin feat/my-contribution
```
---
## ชุมชน & สนับสนุน
- [GitHub Discussions](https://github.com/affaan-m/everything-claude-code/discussions) — ถาม-ตอบ, โชว์ผลงาน
- [GitHub Sponsors](https://github.com/sponsors/affaan-m) — สนับสนุน OSS เริ่มที่ $5/เดือน
- [ECC Pro](https://ecc.tools/pricing) — private repo + GitHub App ($19/seat/เดือน)
- [ECC Tools GitHub App](https://github.com/marketplace/ecc-tools) — ติดตั้ง, PR audit, มี free tier
**OSS ยังคงฟรีตลอดไป** Repo นี้ใช้สัญญาอนุญาต MIT ตลอดกาล ECC Pro คือ GitHub App ที่ host ไว้สำหรับ private repo ส่วน Sponsors และ Pro subscribers ช่วยสนับสนุนให้ maintainer คนเดียวสามารถส่งงานข้าม 7 harness ได้ทุกสัปดาห์
---
## License
[MIT](../../LICENSE)
+1 -1
View File
@@ -23,7 +23,7 @@
**Dil / Language / 语言 / 語言 / Язык / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [**Türkçe**](README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [**Türkçe**](README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+2 -2
View File
@@ -1,4 +1,4 @@
**Ngôn ngữ:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt**
**Ngôn ngữ:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md)
# Everything Claude Code
@@ -18,7 +18,7 @@
**Ngôn ngữ / Language / 语言 / 語言 / Dil / Язык**
[English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt**
[English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md)
</div>
+2 -2
View File
@@ -1,4 +1,4 @@
**语言:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
**语言:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
# Everything Claude Code
@@ -25,7 +25,7 @@
**语言 / Language / 語言 / Dil / Язык / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+1 -1
View File
@@ -13,7 +13,7 @@
**Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ**
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md)
[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | **繁體中文** | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md)
</div>
+2
View File
@@ -80,6 +80,7 @@
"scripts/observability-readiness.js",
"scripts/operator-readiness-dashboard.js",
"scripts/platform-audit.js",
"scripts/preview-pack-smoke.js",
"scripts/hooks/",
"scripts/install-apply.js",
"scripts/install-plan.js",
@@ -300,6 +301,7 @@
"harness:audit": "node scripts/harness-audit.js",
"observability:ready": "node scripts/observability-readiness.js",
"operator:dashboard": "node scripts/operator-readiness-dashboard.js",
"preview-pack:smoke": "node scripts/preview-pack-smoke.js",
"platform:audit": "node scripts/platform-audit.js",
"discussion:audit": "node scripts/discussion-audit.js",
"security:ioc-scan": "node scripts/ci/scan-supply-chain-iocs.js",
+22 -1
View File
@@ -387,6 +387,14 @@ const PAYLOAD_FILENAMES = new Set([
'shai-hulud-workflow.yml',
]);
function normalizedPath(filePath) {
return filePath.split(path.sep).join('/');
}
function isGhTokenMonitorTokenPath(filePath) {
return /\/\.config\/gh-token-monitor\/token$/.test(normalizedPath(filePath));
}
const IGNORED_DIRS = new Set([
'.git',
'.next',
@@ -404,7 +412,7 @@ function normalizeForMatch(value) {
}
function isInSpecialConfigPath(filePath) {
const normalized = filePath.split(path.sep).join('/');
const normalized = normalizedPath(filePath);
return /\/\.claude\//.test(normalized)
|| /\/\.vscode\//.test(normalized)
|| /\/\.kiro\/settings\//.test(normalized)
@@ -416,6 +424,7 @@ function isInSpecialConfigPath(filePath) {
function shouldInspectFile(filePath) {
const base = path.basename(filePath);
if (isGhTokenMonitorTokenPath(filePath)) return true;
if (DEPENDENCY_FILENAMES.has(base)) return true;
if (PERSISTENCE_FILENAMES.has(base) && isInSpecialConfigPath(filePath)) return true;
if (PAYLOAD_FILENAMES.has(base) && filePath.includes(`${path.sep}node_modules${path.sep}`)) return true;
@@ -600,6 +609,17 @@ function scanFile(filePath, rootDir, findings) {
);
}
if (isGhTokenMonitorTokenPath(filePath)) {
addFinding(
findings,
'critical',
relativePath,
1,
'~/.config/gh-token-monitor/token',
'Known Mini Shai-Hulud dead-man switch token store is present',
);
}
for (const indicator of CRITICAL_TEXT_INDICATORS) {
const index = lowerText.indexOf(normalizeForMatch(indicator));
if (index !== -1) {
@@ -651,6 +671,7 @@ function homeTargets(homeDir) {
'Library/LaunchAgents/com.user.gh-token-monitor.plist',
'.config/systemd/user/gh-token-monitor.service',
'.config/systemd/user/pgsql-monitor.service',
'.config/gh-token-monitor/token',
'.local/bin/gh-token-monitor.sh',
'.local/bin/pgmonitor.py',
].map(relativePath => path.join(homeDir, relativePath));
+92 -27
View File
@@ -11,6 +11,7 @@
const crypto = require('crypto');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { sanitizeSessionId, readBridge, writeBridgeAtomic } = require('../lib/session-bridge');
const { getClaudeDir } = require('../lib/utils');
@@ -19,6 +20,7 @@ const MAX_STDIN = 1024 * 1024;
const MAX_FILES_TRACKED = 200;
const RECENT_TOOLS_SIZE = 5;
const HASH_INPUT_LIMIT = 2048;
const WARNING_CACHE_PREFIX = 'ecc-metrics-cost-warnings-';
function toNumber(value) {
const n = Number(value);
@@ -76,41 +78,104 @@ function extractFilePaths(toolName, toolInput) {
return paths;
}
function getCostWarningCachePath(costsPath) {
const hash = crypto.createHash('sha256').update(costsPath).digest('hex').slice(0, 16);
return path.join(os.tmpdir(), `${WARNING_CACHE_PREFIX}${hash}.json`);
}
function readCostWarningCache(cachePath) {
try {
const parsed = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
} catch {
return {};
}
}
function writeCostWarningIfChanged(kind, costsPath, signature, message) {
const cachePath = getCostWarningCachePath(costsPath);
const cache = readCostWarningCache(cachePath);
if (cache[kind] === signature) return;
process.stderr.write(message);
try {
const next = { ...cache, [kind]: signature };
const tmp = `${cachePath}.${process.pid}.tmp`;
fs.writeFileSync(tmp, JSON.stringify(next), 'utf8');
fs.renameSync(tmp, cachePath);
} catch {
// Warning-cache persistence is best effort; never block hook execution.
}
}
/**
* Read cumulative cost for a session from the tail of costs.jsonl.
* Reads last 8KB to avoid scanning entire file.
* Read cumulative cost for a session from costs.jsonl.
*
* Scans the full file because each row is a cumulative session total
* (see cost-tracker.js docblock) and the row we need is the last one
* matching `sessionId`. The previous implementation read only the
* trailing 8 KiB; any session whose latest cumulative row was pushed
* past that window by newer rows from other sessions silently dropped
* to zero the opposite sign of the double-count bug fixed in the
* previous commit.
*
* costs.jsonl is append-only and unbounded today (no rotation in
* cost-tracker.js). At a typical ~150 bytes per row, even 100k rows
* is ~15 MB and a single sync read on every PostToolUse hook is in
* the low milliseconds. If rotation lands later, this scan becomes
* even cheaper.
*/
function readSessionCost(sessionId) {
let costsPath = path.join('metrics', 'costs.jsonl');
try {
const costsPath = path.join(getClaudeDir(), 'metrics', 'costs.jsonl');
const stat = fs.statSync(costsPath);
const readSize = Math.min(stat.size, 8192);
const fd = fs.openSync(costsPath, 'r');
try {
const buf = Buffer.alloc(readSize);
fs.readSync(fd, buf, 0, readSize, Math.max(0, stat.size - readSize));
const lines = buf.toString('utf8').split('\n').filter(Boolean);
costsPath = path.join(getClaudeDir(), 'metrics', 'costs.jsonl');
const content = fs.readFileSync(costsPath, 'utf8');
const lines = content.split('\n').filter(Boolean);
let totalCost = 0;
let totalIn = 0;
let totalOut = 0;
for (const line of lines) {
try {
const row = JSON.parse(line);
if (row.session_id === sessionId) {
totalCost += toNumber(row.estimated_cost_usd);
totalIn += toNumber(row.input_tokens);
totalOut += toNumber(row.output_tokens);
}
} catch {
/* skip malformed lines */
let totalCost = 0;
let totalIn = 0;
let totalOut = 0;
let malformed = 0;
const malformedHasher = crypto.createHash('sha256');
for (const line of lines) {
try {
const row = JSON.parse(line);
if (row.session_id === sessionId) {
totalCost = toNumber(row.estimated_cost_usd);
totalIn = toNumber(row.input_tokens);
totalOut = toNumber(row.output_tokens);
}
} catch {
malformed += 1;
malformedHasher.update(line).update('\0');
}
return { totalCost, totalIn, totalOut };
} finally {
fs.closeSync(fd);
}
} catch {
// One aggregated breadcrumb per call rather than one per bad row, so a
// log-flooded costs.jsonl stays diagnosable without overwhelming stderr.
// Suppress repeats for the same malformed-line signature across hook
// subprocesses, so a persistent bad row should not spam stderr.
if (malformed > 0) {
writeCostWarningIfChanged(
'malformed',
costsPath,
`${malformed}:${malformedHasher.digest('hex').slice(0, 16)}`,
`[ecc-metrics-bridge] skipped ${malformed} malformed line(s) in ${costsPath}\n`
);
}
return { totalCost, totalIn, totalOut };
} catch (err) {
// ENOENT is the common case (no Stop event has fired yet this session)
// and is not actually a failure — stay silent on it. Anything else
// (permission, EISDIR, malformed read) deserves a breadcrumb because
// the bridge will silently report zero cost otherwise.
if (err && err.code !== 'ENOENT') {
writeCostWarningIfChanged(
'read-error',
costsPath,
`${err.code || err.name || 'error'}:${err.message || String(err)}`,
`[ecc-metrics-bridge] failing open after ${err.name || 'error'} reading ${costsPath}: ${err.message || String(err)}\n`
);
}
return { totalCost: 0, totalIn: 0, totalOut: 0 };
}
}
+191 -28
View File
@@ -243,6 +243,14 @@ function includesAll(text, needles) {
return needles.every(needle => text.includes(needle));
}
const LOCALIZATION_MANUAL_REVIEW_TAIL = [
'#1687 zh-CN localization tail',
'#1609 Persian README translation',
'#1563 zh-TW README sync',
'#1564 Turkish README sync',
'#1565 pt-BR README sync',
];
function hasLegacySalvageTracking({ stalePrSalvage, legacyInventory, roadmap }) {
return stalePrSalvage.includes('Manual review tail')
|| stalePrSalvage.includes('Remaining Manual-Review Backlog')
@@ -251,6 +259,39 @@ function hasLegacySalvageTracking({ stalePrSalvage, legacyInventory, roadmap })
|| roadmap.includes('ITO-55');
}
function hasAttachedLegacyManualReviewTail({ stalePrSalvage, legacyInventory, roadmap }) {
return stalePrSalvage.includes('Linear ITO-55')
&& legacyInventory.includes('ITO-55')
&& roadmap.includes('ITO-55')
&& LOCALIZATION_MANUAL_REVIEW_TAIL.every(item => (
stalePrSalvage.includes(item) && legacyInventory.includes(item)
));
}
function legacySalvageStatus(context) {
if (hasAttachedLegacyManualReviewTail(context)) {
return 'current';
}
return hasLegacySalvageTracking(context) ? 'in_progress' : 'not_complete';
}
function legacySalvageEvidence(context) {
if (hasAttachedLegacyManualReviewTail(context)) {
return 'legacy salvage ledger and inventory are current; all localization tails are attached to Linear ITO-55 for manual language-owner review';
}
return 'legacy salvage ledger and ITO-55 tracking are present';
}
function legacySalvageGap(context) {
if (hasAttachedLegacyManualReviewTail(context)) {
return 'repeat legacy scan before release';
}
return 'final translation/manual-review tail remains';
}
function hasAgentShieldEnterpriseTracking(roadmap) {
return roadmap.includes('AgentShield Enterprise Iteration')
&& (
@@ -264,10 +305,17 @@ function hasAgentShieldEnterpriseTracking(roadmap) {
|| roadmap.includes('AgentShield #91')
|| roadmap.includes('checksum-backed policy export')
|| roadmap.includes('#78-#90')
|| roadmap.includes('hosted promotion judge audit traces')
|| roadmap.includes('operator-visible promotion output values')
);
}
function agentShieldEnterpriseGap(roadmap) {
if (roadmap.includes('hosted promotion judge audit traces')
|| roadmap.includes('operator-visible promotion output values')) {
return 'deepen live operator approval/readback after Marketplace/payment gates';
}
if (roadmap.includes('#78-#92')
|| roadmap.includes('AgentShield PR #92')
|| roadmap.includes('AgentShield #92')
@@ -284,6 +332,103 @@ function agentShieldEnterpriseGap(roadmap) {
: 'durable policy export and fleet-review workflow automation remain pending after reviewItems shipped';
}
function agentShieldEnterpriseEvidence(roadmap) {
if (roadmap.includes('hosted promotion judge audit traces')
|| roadmap.includes('operator-visible promotion output values')) {
return 'AgentShield policy promotion `reviewItems` landed in `87aec47`; package-manager hardening drift detection landed in `28d08c7`; workflow action runtime pins were refreshed in `659f569`; npm age-gate guidance was corrected in `ee585cd`; package-manager hardening Action outputs landed in `1124535`; policy-promotion Action outputs and runtime-smoke job-summary evidence landed in `1593925`; ECC-Tools consumes those outputs in `8658951`, surfaces operator-readable status/pack/count/digest telemetry in `16c537f`, and renders hosted promotion judge audit traces in `05d4e82`; all are mirrored in the GA roadmap';
}
return 'AgentShield enterprise PR evidence is mirrored in the GA roadmap';
}
function eccToolsNextLevelEvidence(roadmap) {
if (roadmap.includes('production Marketplace readback state')
|| roadmap.includes('eb69412')) {
return 'billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output telemetry, operator-visible promotion output details, hosted promotion judge audit traces, billing announcement preflight, and production KV readback state are mirrored in the GA roadmap';
}
if (roadmap.includes('hosted promotion judge audit traces')
|| roadmap.includes('operator-visible promotion output values')) {
return 'billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output telemetry, operator-visible promotion output details, and hosted promotion judge audit traces are mirrored in the GA roadmap';
}
return 'billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, and harness-route policy linking are mirrored in the GA roadmap';
}
function eccToolsNextLevelGap(roadmap) {
if (roadmap.includes('production Marketplace readback state')
|| roadmap.includes('eb69412')) {
return 'complete Marketplace purchase/webhook readback, then run the live announcement gate';
}
if (roadmap.includes('hosted promotion judge audit traces')
|| roadmap.includes('operator-visible promotion output values')) {
return 'live Marketplace test-account readback pending';
}
return 'live Marketplace test-account readback, hosted promotion telemetry, and richer operator review UX pending';
}
function supplyChainLocalProtectionEvidence({ roadmap, scripts }) {
if (scripts['security:advisory-sources'] === 'node scripts/ci/supply-chain-advisory-sources.js'
&& roadmap.includes('package-manager hardening Action outputs')) {
return 'scheduled supply-chain watch emits IOC/advisory-source refresh artifacts; ECC scanner covers gh-token-monitor token-store persistence; AgentShield now detects known AI-tool persistence IOCs, npm lifecycle/token drift, unsupported npm age-key drift, and pnpm/Yarn cooldown drift; ITO-57 has May 17 Linear evidence updates';
}
return scripts['security:advisory-sources'] === 'node scripts/ci/supply-chain-advisory-sources.js'
? 'scheduled supply-chain watch now emits IOC and advisory-source refresh artifacts'
: 'scheduled supply-chain watch or advisory-source command is missing';
}
function supplyChainLocalProtectionGap({ roadmap, scripts }) {
if (scripts['security:advisory-sources'] === 'node scripts/ci/supply-chain-advisory-sources.js'
&& roadmap.includes('package-manager hardening Action outputs')) {
return 'repeat advisory/source refresh and Linear sync after each significant supply-chain batch';
}
return 'Linear status synchronization remains ITO-57 follow-up after each significant merge batch';
}
function hasCurrentLinearProgressSync({ roadmap, progressSync }) {
return includesAll(roadmap, [
'Linear live sync is current',
'operator progress snapshot',
]) && includesAll(progressSync, [
'node scripts/work-items.js sync-github --repo <owner/repo>',
'node scripts/status.js --json',
'Linear remains the external status surface',
]);
}
function hasLinearProgressContract({ roadmap, progressSync }) {
return includesAll(roadmap, ['ITO-44', 'ITO-59', 'Linear'])
&& includesAll(progressSync, ['GitHub', 'Linear', 'handoff', 'repo roadmap']);
}
function linearProgressStatus(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'current';
}
return hasLinearProgressContract(context) ? 'in_progress' : 'not_complete';
}
function linearProgressEvidence(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'Linear live sync and project progress snapshot are current; progress-sync contract defines the file-backed work-items/status path';
}
return 'repo mirror and progress-sync contract are present';
}
function linearProgressGap(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'repeat Linear/project status update and local work-items sync after each significant merge batch';
}
return 'recurring Linear status sync and productized realtime sync remain pending';
}
function runCommand(command, args, options = {}) {
const result = spawnSync(command, args, {
cwd: options.cwd,
@@ -324,6 +469,7 @@ function buildRequirements(rootDir, platformReport) {
const publicationReadiness = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-readiness.md');
const namingMatrix = readText(rootDir, 'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md');
const previewManifest = readText(rootDir, 'docs/releases/2.0.0-rc.1/preview-pack-manifest.md');
const previewPackSmoke = readText(rootDir, 'scripts/preview-pack-smoke.js');
const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md');
const observabilityReadiness = readText(rootDir, 'docs/architecture/observability-readiness.md');
const stalePrSalvage = readText(rootDir, 'docs/stale-pr-salvage-ledger.md');
@@ -332,6 +478,23 @@ function buildRequirements(rootDir, platformReport) {
const supplyChainWorkflow = readText(rootDir, '.github/workflows/supply-chain-watch.yml');
const packageJson = readPackage(rootDir);
const scripts = packageJson.scripts || {};
const legacyContext = { stalePrSalvage, legacyInventory, roadmap };
const previewPackManifestReady = includesAll(previewManifest, [
'publication-readiness.md',
'release-notes.md',
'quickstart.md'
]);
const previewPackSmokeReady = scripts['preview-pack:smoke'] === 'node scripts/preview-pack-smoke.js'
&& fileExists(rootDir, 'scripts/preview-pack-smoke.js')
&& includesAll(previewManifest, ['scripts/preview-pack-smoke.js', 'npm run preview-pack:smoke'])
&& includesAll(previewPackSmoke, [
'ecc.preview-pack-smoke.v1',
'preview-pack-artifacts-present',
'hermes-boundary-sanitized',
'publication-blockers-preserved'
]);
const hermesArtifactsReady = fileExists(rootDir, 'docs/HERMES-SETUP.md')
&& fileExists(rootDir, 'skills/hermes-imports/SKILL.md');
const githubLive = !platformReport.github.skipped && platformReport.github.totals.errors === 0;
const queuesCurrent = githubLive
@@ -389,23 +552,29 @@ function buildRequirements(rootDir, platformReport) {
'ecc-preview-pack',
'ECC 2.0 preview pack ready',
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md',
includesAll(previewManifest, ['publication-readiness.md', 'release-notes.md', 'quickstart.md']) ? 'in_progress' : 'not_complete',
includesAll(previewManifest, ['publication-readiness.md', 'release-notes.md', 'quickstart.md'])
previewPackManifestReady && previewPackSmokeReady ? 'current' : previewPackManifestReady ? 'in_progress' : 'not_complete',
previewPackManifestReady && previewPackSmokeReady
? 'preview pack manifest and deterministic smoke gate are in-tree'
: previewPackManifestReady
? 'preview pack manifest is in-tree'
: 'preview pack manifest is incomplete',
'final clean-checkout release approval and publish evidence still pending'
previewPackManifestReady && previewPackSmokeReady
? 'repeat clean-checkout preview-pack smoke before publication'
: 'final clean-checkout release approval and publish evidence still pending'
),
buildRequirement(
'hermes-specialized-skills',
'Include Hermes specialized skills safely',
'docs/HERMES-SETUP.md and skills/hermes-imports/SKILL.md',
fileExists(rootDir, 'docs/HERMES-SETUP.md') && fileExists(rootDir, 'skills/hermes-imports/SKILL.md')
? 'in_progress'
: 'not_complete',
fileExists(rootDir, 'docs/HERMES-SETUP.md') && fileExists(rootDir, 'skills/hermes-imports/SKILL.md')
hermesArtifactsReady && previewPackSmokeReady ? 'current' : hermesArtifactsReady ? 'in_progress' : 'not_complete',
hermesArtifactsReady && previewPackSmokeReady
? 'Hermes setup/import artifacts are covered by preview-pack smoke'
: hermesArtifactsReady
? 'Hermes setup and import skill are present'
: 'Hermes setup/import artifacts missing',
'final preview-pack smoke and release review pending'
hermesArtifactsReady && previewPackSmokeReady
? 'repeat preview-pack smoke before release review'
: 'final preview-pack smoke and release review pending'
),
buildRequirement(
'naming-and-plugin-publication',
@@ -437,7 +606,7 @@ function buildRequirements(rootDir, platformReport) {
hasAgentShieldEnterpriseTracking(roadmap)
? 'in_progress'
: 'not_complete',
'AgentShield enterprise PR evidence is mirrored in the GA roadmap',
agentShieldEnterpriseEvidence(roadmap),
agentShieldEnterpriseGap(roadmap)
),
buildRequirement(
@@ -447,28 +616,24 @@ function buildRequirements(rootDir, platformReport) {
includesAll(roadmap, ['ECC-Tools PR #78', 'hosted promotion', 'announcementGate'])
? 'in_progress'
: 'not_complete',
'billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, and harness-route policy linking are mirrored in the GA roadmap',
'live Marketplace test-account readback, hosted promotion telemetry, and richer operator review UX pending'
eccToolsNextLevelEvidence(roadmap),
eccToolsNextLevelGap(roadmap)
),
buildRequirement(
'legacy-salvage',
'Audit, prune, or attach legacy work',
'docs/stale-pr-salvage-ledger.md and legacy inventory',
hasLegacySalvageTracking({ stalePrSalvage, legacyInventory, roadmap })
? 'in_progress'
: 'not_complete',
'legacy salvage ledger and ITO-55 tracking are present',
'final translation/manual-review tail remains'
legacySalvageStatus(legacyContext),
legacySalvageEvidence(legacyContext),
legacySalvageGap(legacyContext)
),
buildRequirement(
'linear-roadmap-and-progress',
'Keep Linear roadmap detailed and progress tracking synchronized',
'Linear project mirror plus progress-sync contract',
includesAll(roadmap, ['ITO-44', 'ITO-59', 'Linear']) && includesAll(progressSync, ['GitHub', 'Linear', 'handoff', 'repo roadmap'])
? 'in_progress'
: 'not_complete',
'repo mirror and progress-sync contract are present',
'recurring Linear status sync and productized realtime sync remain pending'
linearProgressStatus({ roadmap, progressSync }),
linearProgressEvidence({ roadmap, progressSync }),
linearProgressGap({ roadmap, progressSync })
),
buildRequirement(
'observability-for-self-use',
@@ -486,17 +651,15 @@ function buildRequirements(rootDir, platformReport) {
buildRequirement(
'supply-chain-local-protection',
'Keep Mini Shai-Hulud/TanStack protection loop current',
'supply-chain watch plus runbook',
'supply-chain watch plus runbook plus AgentShield package-manager hardening',
includesAll(supplyChainRunbook, ['TanStack', 'Mini Shai-Hulud', 'scan-supply-chain-iocs.js', 'supply-chain-advisory-sources.js'])
&& includesAll(supplyChainWorkflow, ['supply-chain-advisory-sources.js', 'supply-chain-advisory-sources.json'])
&& scripts['security:advisory-sources'] === 'node scripts/ci/supply-chain-advisory-sources.js'
&& fileExists(rootDir, '.github/workflows/supply-chain-watch.yml')
? 'current'
: 'in_progress',
scripts['security:advisory-sources'] === 'node scripts/ci/supply-chain-advisory-sources.js'
? 'scheduled supply-chain watch now emits IOC and advisory-source refresh artifacts'
: 'scheduled supply-chain watch or advisory-source command is missing',
'Linear status synchronization remains ITO-57 follow-up after each significant merge batch'
supplyChainLocalProtectionEvidence({ roadmap, scripts }),
supplyChainLocalProtectionGap({ roadmap, scripts })
),
];
}
@@ -549,8 +712,8 @@ function buildReport(options) {
top_actions: topActions,
next_work_order: [
'Regenerate this dashboard from the final release commit before publication evidence is recorded.',
'Continue ITO-57 with Linear status synchronization for the scheduled supply-chain watch advisory-source report.',
'Advance ECC Tools live Marketplace test-account readback before publishing native-payments announcement copy.',
'Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.',
'Complete ECC Tools Marketplace purchase/webhook readback, then run preflight and the live announcement gate before publishing native-payments copy.',
'Resume ITO-45, ITO-46, and ITO-56 only after the generated dashboard and final release gates are refreshed.',
],
};
+349
View File
@@ -0,0 +1,349 @@
#!/usr/bin/env node
'use strict';
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const RELEASE = '2.0.0-rc.1';
const RELEASE_DIR = `docs/releases/${RELEASE}`;
const SCHEMA_VERSION = 'ecc.preview-pack-smoke.v1';
const REQUIRED_ARTIFACTS = [
'README.md',
'docs/HERMES-SETUP.md',
'skills/hermes-imports/SKILL.md',
'docs/architecture/cross-harness.md',
'docs/architecture/harness-adapter-compliance.md',
'docs/architecture/observability-readiness.md',
'docs/architecture/progress-sync-contract.md',
'scripts/preview-pack-smoke.js',
`${RELEASE_DIR}/release-notes.md`,
`${RELEASE_DIR}/quickstart.md`,
`${RELEASE_DIR}/launch-checklist.md`,
`${RELEASE_DIR}/publication-readiness.md`,
`${RELEASE_DIR}/publication-evidence-2026-05-15.md`,
`${RELEASE_DIR}/publication-evidence-2026-05-16.md`,
`${RELEASE_DIR}/publication-evidence-2026-05-17.md`,
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-17.md`,
`${RELEASE_DIR}/naming-and-publication-matrix.md`,
`${RELEASE_DIR}/x-thread.md`,
`${RELEASE_DIR}/linkedin-post.md`,
`${RELEASE_DIR}/article-outline.md`,
`${RELEASE_DIR}/telegram-handoff.md`,
`${RELEASE_DIR}/demo-prompts.md`,
];
const REQUIRED_VERIFICATION_COMMANDS = [
'git status --short --branch',
'node scripts/platform-audit.js --format json --allow-untracked docs/drafts/',
'npm run preview-pack:smoke',
'npm run harness:adapters -- --check',
'npm run harness:audit -- --format json',
'npm run observability:ready',
'npm run security:ioc-scan',
'npm audit --audit-level=moderate',
'npm audit signatures',
'node tests/docs/ecc2-release-surface.test.js',
'node tests/run-all.js',
'cd ecc2 && cargo test',
];
const REQUIRED_PUBLICATION_BLOCKERS = [
'GitHub prerelease `v2.0.0-rc.1`',
'npm `ecc-universal@2.0.0-rc.1`',
'Claude plugin tag',
'Codex repo-marketplace distribution evidence',
'ECC Tools billing/product readiness',
];
const HERMES_BOUNDARY_MARKERS = [
'Public Release Candidate Scope',
'ECC v2.0.0-rc.1 documents the Hermes surface',
'Sanitization Checklist',
'Do not ship raw workspace exports',
'Output Contract',
];
function usage() {
console.log([
'Usage: node scripts/preview-pack-smoke.js [--format <text|json>] [--root <dir>]',
'',
'Deterministic smoke gate for the ECC 2.0 rc.1 preview pack.',
'',
'Options:',
' --format <text|json> Output format (default: text)',
' --root <dir> Repository root to inspect (default: cwd)',
' --help, -h Show this help',
].join('\n'));
}
function readArgValue(args, index, flagName) {
const value = args[index + 1];
if (!value || value.startsWith('--')) {
throw new Error(`${flagName} requires a value`);
}
return value;
}
function parseArgs(argv) {
const args = argv.slice(2);
const parsed = {
format: 'text',
help: false,
root: path.resolve(process.cwd()),
};
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === '--help' || arg === '-h') {
parsed.help = true;
continue;
}
if (arg === '--format') {
parsed.format = readArgValue(args, index, arg).toLowerCase();
index += 1;
continue;
}
if (arg.startsWith('--format=')) {
parsed.format = arg.slice('--format='.length).toLowerCase();
continue;
}
if (arg === '--root') {
parsed.root = path.resolve(readArgValue(args, index, arg));
index += 1;
continue;
}
if (arg.startsWith('--root=')) {
parsed.root = path.resolve(arg.slice('--root='.length));
continue;
}
throw new Error(`Unknown argument: ${arg}`);
}
if (!['text', 'json'].includes(parsed.format)) {
throw new Error(`Invalid format: ${parsed.format}. Use text or json.`);
}
return parsed;
}
function readText(rootDir, relativePath) {
try {
return fs.readFileSync(path.join(rootDir, relativePath), 'utf8');
} catch (_error) {
return '';
}
}
function fileExists(rootDir, relativePath) {
return fs.existsSync(path.join(rootDir, relativePath));
}
function safeParseJson(text) {
if (!text.trim()) {
return null;
}
try {
return JSON.parse(text);
} catch (_error) {
return null;
}
}
function lineNumberForIndex(text, index) {
return text.slice(0, index).split('\n').length;
}
function findForbiddenContent(rootDir, relativePaths) {
const offenders = [];
const privatePathPattern = /\/Users\/(?!\.\.\.)[A-Za-z0-9._-]+|\/home\/(?!user|runner)[A-Za-z0-9._-]+/g;
for (const relativePath of relativePaths) {
const text = readText(rootDir, relativePath);
if (!text) {
continue;
}
for (const match of text.matchAll(privatePathPattern)) {
offenders.push({
path: relativePath,
line: lineNumberForIndex(text, match.index),
marker: match[0],
});
}
}
return offenders;
}
function makeCheck(id, status, evidence, fix) {
return {
id,
status,
evidence,
fix: status === 'pass' ? '' : fix,
};
}
function buildReport(options = {}) {
const rootDir = path.resolve(options.root || process.cwd());
const packageJson = safeParseJson(readText(rootDir, 'package.json')) || {};
const packageScripts = packageJson.scripts || {};
const packageFiles = Array.isArray(packageJson.files) ? packageJson.files : [];
const manifestPath = `${RELEASE_DIR}/preview-pack-manifest.md`;
const manifest = readText(rootDir, manifestPath);
const hermesSetup = readText(rootDir, 'docs/HERMES-SETUP.md');
const hermesSkill = readText(rootDir, 'skills/hermes-imports/SKILL.md');
const missingArtifacts = REQUIRED_ARTIFACTS.filter(relativePath => !fileExists(rootDir, relativePath));
const unlistedArtifacts = REQUIRED_ARTIFACTS.filter(relativePath => !manifest.includes(`\`${relativePath}\``));
const missingCommands = REQUIRED_VERIFICATION_COMMANDS.filter(command => !manifest.includes(command));
const missingBlockers = REQUIRED_PUBLICATION_BLOCKERS.filter(blocker => !manifest.includes(blocker));
const missingHermesMarkers = HERMES_BOUNDARY_MARKERS.filter(marker => !`${hermesSetup}\n${hermesSkill}`.includes(marker));
const forbiddenContent = findForbiddenContent(rootDir, [
...REQUIRED_ARTIFACTS,
manifestPath,
'docs/business/social-launch-copy.md',
]);
const checks = [
makeCheck(
'preview-pack-script-registered',
packageScripts['preview-pack:smoke'] === 'node scripts/preview-pack-smoke.js'
&& packageFiles.includes('scripts/preview-pack-smoke.js')
&& fileExists(rootDir, 'scripts/preview-pack-smoke.js')
? 'pass'
: 'fail',
'package script and npm package file entry for preview-pack smoke gate',
'Add preview-pack:smoke to package scripts and include scripts/preview-pack-smoke.js in package files.'
),
makeCheck(
'preview-pack-artifacts-present',
missingArtifacts.length === 0 && unlistedArtifacts.length === 0 ? 'pass' : 'fail',
missingArtifacts.length === 0 && unlistedArtifacts.length === 0
? `${REQUIRED_ARTIFACTS.length} required artifacts exist and are listed in the manifest`
: `missing artifacts: ${missingArtifacts.join(', ') || 'none'}; unlisted artifacts: ${unlistedArtifacts.join(', ') || 'none'}`,
'Restore missing preview-pack artifacts and list every required artifact in preview-pack-manifest.md.'
),
makeCheck(
'final-verification-commands-listed',
missingCommands.length === 0 ? 'pass' : 'fail',
missingCommands.length === 0
? `${REQUIRED_VERIFICATION_COMMANDS.length} final verification commands are listed`
: `missing commands: ${missingCommands.join('; ')}`,
'Add the missing final verification commands to preview-pack-manifest.md.'
),
makeCheck(
'hermes-boundary-sanitized',
missingHermesMarkers.length === 0 && forbiddenContent.length === 0 ? 'pass' : 'fail',
missingHermesMarkers.length === 0 && forbiddenContent.length === 0
? 'Hermes setup and import skill preserve the public sanitization boundary'
: `missing markers: ${missingHermesMarkers.join(', ') || 'none'}; forbidden content: ${forbiddenContent.map(item => `${item.path}:${item.line}`).join(', ') || 'none'}`,
'Restore Hermes sanitization language and remove private local paths from preview-pack docs.'
),
makeCheck(
'publication-blockers-preserved',
missingBlockers.length === 0
&& /approval-gated release, package, plugin, and\s+announcement steps/.test(manifest)
? 'pass'
: 'fail',
missingBlockers.length === 0
? 'publication remains explicitly approval-gated'
: `missing blockers: ${missingBlockers.join(', ')}`,
'Keep publication blockers explicit until the live release, package, plugin, and billing surfaces exist.'
),
];
const failed = checks.filter(check => check.status !== 'pass');
const digest = crypto
.createHash('sha256')
.update(JSON.stringify(checks.map(check => [check.id, check.status, check.evidence])))
.digest('hex')
.slice(0, 12);
return {
schema_version: SCHEMA_VERSION,
release: RELEASE,
ready: failed.length === 0,
digest,
summary: {
passed: checks.length - failed.length,
failed: failed.length,
total: checks.length,
},
checks,
};
}
function renderText(report) {
const lines = [
'ECC preview pack smoke',
`Release: ${report.release}`,
`Ready: ${report.ready ? 'yes' : 'no'}`,
`Digest: ${report.digest}`,
'',
'Checks:',
];
for (const check of report.checks) {
lines.push(`- ${check.status} ${check.id}: ${check.evidence}`);
if (check.fix) {
lines.push(` fix: ${check.fix}`);
}
}
lines.push('');
lines.push(`Passed: ${report.summary.passed}`);
lines.push(`Failed: ${report.summary.failed}`);
return `${lines.join('\n')}\n`;
}
function main() {
let parsed;
try {
parsed = parseArgs(process.argv);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
if (parsed.help) {
usage();
return;
}
const report = buildReport({ root: parsed.root });
if (parsed.format === 'json') {
console.log(JSON.stringify(report, null, 2));
} else {
process.stdout.write(renderText(report));
}
if (!report.ready) {
process.exit(2);
}
}
if (require.main === module) {
main();
}
module.exports = {
REQUIRED_ARTIFACTS,
REQUIRED_PUBLICATION_BLOCKERS,
REQUIRED_VERIFICATION_COMMANDS,
buildReport,
parseArgs,
renderText,
};
+12
View File
@@ -365,6 +365,18 @@ function run() {
});
})) passed++; else failed++;
if (test('rejects Mini Shai-Hulud gh-token-monitor token store when home scan is enabled', () => {
withFixture({
'home/.config/gh-token-monitor/token': 'redacted-token-placeholder',
}, rootDir => {
const homeDir = path.join(rootDir, 'home');
const result = scanSupplyChainIocs({ rootDir, home: true, homeDir });
assert.ok(result.findings.some(
finding => finding.indicator === '~/.config/gh-token-monitor/token',
));
});
})) passed++; else failed++;
if (test('rejects installed payload filenames in node_modules', () => {
withFixture({
'node_modules/@tanstack/react-router/router_init.js': '/* payload */',
+4
View File
@@ -171,6 +171,7 @@ test('preview pack manifest assembles release, Hermes, and publication gates', (
'docs/HERMES-SETUP.md',
'skills/hermes-imports/SKILL.md',
'docs/architecture/harness-adapter-compliance.md',
'scripts/preview-pack-smoke.js',
'docs/releases/2.0.0-rc.1/publication-readiness.md',
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md',
]) {
@@ -189,6 +190,7 @@ test('preview pack manifest assembles release, Hermes, and publication gates', (
assert.ok(manifest.includes('no raw workspace exports'));
assert.ok(manifest.includes('Final Verification Commands'));
assert.ok(manifest.includes('npm run preview-pack:smoke'));
assert.ok(manifest.includes('Reference-Inspired Adapter Direction'));
});
@@ -263,6 +265,8 @@ test('publication readiness checklist gates public release actions on evidence',
}
assert.ok(source.includes('publication-evidence-2026-05-15.md'));
assert.ok(source.includes('Preview-pack smoke'));
assert.ok(source.includes('npm run preview-pack:smoke'));
assert.ok(may15Evidence.includes('PR #1921'));
assert.ok(may15Evidence.includes('PR #1933'));
assert.ok(may15Evidence.includes('PR #1934'));
+12 -1
View File
@@ -131,9 +131,20 @@ test('legacy command shim table tracks the current archive contents', () => {
test('stale salvage backlog records the remaining manual-review tail', () => {
const source = read('docs/legacy-artifact-inventory.md');
assert.ok(source.includes('#1687 zh-CN localization tail'));
for (const pr of [
'#1687 zh-CN localization tail',
'#1609 Persian README translation',
'#1563 zh-TW README sync',
'#1564 Turkish README sync',
'#1565 pt-BR README sync',
]) {
assert.ok(source.includes(pr), `Missing manual-review inventory row for ${pr}`);
}
assert.ok(source.includes('Translator/manual review'));
assert.ok(source.includes('#1746-#1752'));
assert.ok(source.includes('ITO-55'));
assert.ok(source.includes('no automatic import remains release-blocking'));
});
if (failed > 0) {
+6 -1
View File
@@ -88,7 +88,9 @@ test('stale PR salvage ledger keeps localization tails manual-review only', () =
assert.ok(source.includes('#1609 Persian README translation'));
assert.ok(source.includes('#1563 zh-TW README sync'));
assert.ok(source.includes('translator/manual review'));
assert.ok(source.includes('Linear ITO-55'));
assert.ok(source.includes('Do not import stale top-level docs'));
assert.ok(source.includes('not a release-blocking salvage task'));
});
test('legacy inventory and roadmap link to the durable salvage ledger', () => {
@@ -97,7 +99,10 @@ test('legacy inventory and roadmap link to the durable salvage ledger', () => {
assert.ok(inventory.includes('docs/stale-pr-salvage-ledger.md'));
assert.ok(roadmap.includes('docs/stale-pr-salvage-ledger.md'));
assert.ok(roadmap.includes('#1687 translator/manual'));
assert.ok(roadmap.includes('#1687, #1609, #1563, #1564'));
assert.ok(roadmap.includes('Linear ITO-55'));
assert.ok(roadmap.includes('#1609'));
assert.ok(roadmap.includes('no automatic import remains release-blocking'));
});
test('stale PR salvage ledger records the May 12 gap pass', () => {
+211
View File
@@ -5,6 +5,7 @@
*/
const assert = require('assert');
const { spawnSync } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
@@ -145,6 +146,216 @@ function runTests() {
passed++;
else failed++;
if (
test('readSessionCost returns the LAST cumulative row, not the sum (cost-tracker contract)', () => {
// cost-tracker.js writes one row per Stop event; each row is already
// a cumulative session total ("To get per-session cost, take the
// last row per session_id."). Summing across rows over-counts:
// 0.01 + 0.02 + 0.03 = 0.06, but the correct answer is 0.03.
const tmpHome = makeTempHome();
const originalHome = process.env.HOME;
const originalUserProfile = process.env.USERPROFILE;
try {
process.env.HOME = tmpHome;
process.env.USERPROFILE = tmpHome;
const metricsDir = path.join(tmpHome, '.claude', 'metrics');
fs.mkdirSync(metricsDir, { recursive: true });
fs.writeFileSync(
path.join(metricsDir, 'costs.jsonl'),
[
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.01, input_tokens: 333, output_tokens: 166 }),
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.02, input_tokens: 666, output_tokens: 333 }),
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.03, input_tokens: 1000, output_tokens: 500 })
].join('\n') + '\n',
'utf8'
);
const result = readSessionCost('S1');
assert.strictEqual(result.totalCost, 0.03, `expected last-row 0.03, got ${result.totalCost} (was the bug: 0.06)`);
assert.strictEqual(result.totalIn, 1000);
assert.strictEqual(result.totalOut, 500);
} finally {
if (originalHome === undefined) delete process.env.HOME;
else process.env.HOME = originalHome;
if (originalUserProfile === undefined) delete process.env.USERPROFILE;
else process.env.USERPROFILE = originalUserProfile;
fs.rmSync(tmpHome, { recursive: true, force: true });
}
})
)
passed++;
else failed++;
if (
test('readSessionCost finds session row beyond the old 8 KiB tail boundary', () => {
// The previous implementation read only the trailing 8 KiB of
// costs.jsonl. A long-running deployment where the target session's
// most recent cumulative row sat further back than that — e.g.
// pushed past by many rows from OTHER sessions — silently saw
// cost=0. This test wedges the S1 row at the file start, fills
// ~16 KiB of OTHER-session noise after it, and asserts the S1 row
// is still found.
const tmpHome = makeTempHome();
const originalHome = process.env.HOME;
const originalUserProfile = process.env.USERPROFILE;
try {
process.env.HOME = tmpHome;
process.env.USERPROFILE = tmpHome;
const metricsDir = path.join(tmpHome, '.claude', 'metrics');
fs.mkdirSync(metricsDir, { recursive: true });
const otherRow = JSON.stringify({ session_id: 'OTHER', estimated_cost_usd: 1, input_tokens: 100, output_tokens: 50 });
const s1Row = JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.5, input_tokens: 500, output_tokens: 250 });
const rows = [s1Row, ...Array(200).fill(otherRow)];
fs.writeFileSync(path.join(metricsDir, 'costs.jsonl'), rows.join('\n') + '\n', 'utf8');
// Confirm we're actually past the old 8 KiB ceiling so the test
// would have failed under the previous implementation.
const size = fs.statSync(path.join(metricsDir, 'costs.jsonl')).size;
assert.ok(size > 8192, `setup: expected costs.jsonl > 8 KiB, got ${size} bytes`);
const result = readSessionCost('S1');
assert.strictEqual(result.totalCost, 0.5);
assert.strictEqual(result.totalIn, 500);
assert.strictEqual(result.totalOut, 250);
} finally {
if (originalHome === undefined) delete process.env.HOME;
else process.env.HOME = originalHome;
if (originalUserProfile === undefined) delete process.env.USERPROFILE;
else process.env.USERPROFILE = originalUserProfile;
fs.rmSync(tmpHome, { recursive: true, force: true });
}
})
)
passed++;
else failed++;
if (
test('readSessionCost writes one stderr breadcrumb when malformed lines persist across calls', () => {
// Reviewer (coderabbitai) asked for diagnosability when the inner
// catch silently skips malformed JSON rows. Verify the aggregated
// "skipped N malformed line(s)" breadcrumb appears on stderr while
// the function still recovers the last valid matching row. Because
// this hook runs after every tool invocation, the same bad rows should
// not emit the same warning on every call.
const tmpHome = makeTempHome();
const originalHome = process.env.HOME;
const originalUserProfile = process.env.USERPROFILE;
const originalStderrWrite = process.stderr.write.bind(process.stderr);
let captured = '';
process.stderr.write = chunk => {
captured += String(chunk);
return true;
};
try {
process.env.HOME = tmpHome;
process.env.USERPROFILE = tmpHome;
const metricsDir = path.join(tmpHome, '.claude', 'metrics');
fs.mkdirSync(metricsDir, { recursive: true });
fs.writeFileSync(
path.join(metricsDir, 'costs.jsonl'),
[
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.5, input_tokens: 500, output_tokens: 250 }),
'NOT_JSON',
'{"truncated":',
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.7, input_tokens: 700, output_tokens: 350 }),
].join('\n') + '\n',
'utf8'
);
const result = readSessionCost('S1');
assert.strictEqual(result.totalCost, 0.7, 'last valid row should still win');
const secondResult = readSessionCost('S1');
assert.deepStrictEqual(secondResult, result);
const matches = captured.match(/skipped 2 malformed line\(s\)/g) || [];
assert.strictEqual(matches.length, 1,
`expected one aggregated malformed-line breadcrumb on stderr, got: ${captured}`);
} finally {
process.stderr.write = originalStderrWrite;
if (originalHome === undefined) delete process.env.HOME;
else process.env.HOME = originalHome;
if (originalUserProfile === undefined) delete process.env.USERPROFILE;
else process.env.USERPROFILE = originalUserProfile;
fs.rmSync(tmpHome, { recursive: true, force: true });
}
})
)
passed++;
else failed++;
if (
test('readSessionCost suppresses repeated malformed breadcrumbs across hook subprocesses', () => {
const tmpHome = makeTempHome();
const originalHome = process.env.HOME;
const originalUserProfile = process.env.USERPROFILE;
try {
process.env.HOME = tmpHome;
process.env.USERPROFILE = tmpHome;
const metricsDir = path.join(tmpHome, '.claude', 'metrics');
fs.mkdirSync(metricsDir, { recursive: true });
fs.writeFileSync(
path.join(metricsDir, 'costs.jsonl'),
[
JSON.stringify({ session_id: 'S1', estimated_cost_usd: 0.7, input_tokens: 700, output_tokens: 350 }),
'NOT_JSON',
'{"truncated":'
].join('\n') + '\n',
'utf8'
);
const bridgePath = path.resolve(__dirname, '../../scripts/hooks/ecc-metrics-bridge');
const code = "const { readSessionCost } = require(process.argv[1]); readSessionCost('S1');";
const env = { ...process.env, HOME: tmpHome, USERPROFILE: tmpHome };
const first = spawnSync(process.execPath, ['-e', code, bridgePath], { env, encoding: 'utf8' });
const second = spawnSync(process.execPath, ['-e', code, bridgePath], { env, encoding: 'utf8' });
assert.strictEqual(first.status, 0, first.stderr || first.stdout);
assert.strictEqual(second.status, 0, second.stderr || second.stdout);
assert.match(first.stderr, /skipped 2 malformed line\(s\)/);
assert.strictEqual(second.stderr, '', `expected repeat subprocess warning suppression, got: ${second.stderr}`);
} finally {
if (originalHome === undefined) delete process.env.HOME;
else process.env.HOME = originalHome;
if (originalUserProfile === undefined) delete process.env.USERPROFILE;
else process.env.USERPROFILE = originalUserProfile;
fs.rmSync(tmpHome, { recursive: true, force: true });
}
})
)
passed++;
else failed++;
if (
test('readSessionCost stays silent when costs.jsonl does not exist (ENOENT)', () => {
// ENOENT is the common case before any Stop event has fired — it is
// not a failure and should not produce stderr noise. Other errors
// (permission, EISDIR, etc.) DO produce a breadcrumb, covered by the
// malformed-line test above's surrounding harness.
const tmpHome = makeTempHome();
const originalHome = process.env.HOME;
const originalUserProfile = process.env.USERPROFILE;
const originalStderrWrite = process.stderr.write.bind(process.stderr);
let captured = '';
process.stderr.write = chunk => {
captured += String(chunk);
return true;
};
try {
process.env.HOME = tmpHome;
process.env.USERPROFILE = tmpHome;
// Do NOT create the metrics dir or file — readSessionCost should
// hit ENOENT and return zeros silently.
const result = readSessionCost('S1');
assert.deepStrictEqual(result, { totalCost: 0, totalIn: 0, totalOut: 0 });
assert.strictEqual(captured, '', `expected no stderr on ENOENT, got: ${captured}`);
} finally {
process.stderr.write = originalStderrWrite;
if (originalHome === undefined) delete process.env.HOME;
else process.env.HOME = originalHome;
if (originalUserProfile === undefined) delete process.env.USERPROFILE;
else process.env.USERPROFILE = originalUserProfile;
fs.rmSync(tmpHome, { recursive: true, force: true });
}
})
)
passed++;
else failed++;
if (
test('readSessionCost does not include unrelated default-session rows', () => {
const tmpHome = makeTempHome();
@@ -59,6 +59,7 @@ function buildExpectedPublishPaths(repoRoot) {
"scripts/observability-readiness.js",
"scripts/operator-readiness-dashboard.js",
"scripts/platform-audit.js",
"scripts/preview-pack-smoke.js",
"scripts/skill-create-output.js",
"scripts/repair.js",
"scripts/harness-adapter-compliance.js",
@@ -129,6 +130,7 @@ function main() {
"scripts/consult.js",
"scripts/discussion-audit.js",
"scripts/operator-readiness-dashboard.js",
"scripts/preview-pack-smoke.js",
"scripts/work-items.js",
"scripts/platform-audit.js",
".gemini/GEMINI.md",
@@ -32,18 +32,26 @@ function seedRepo(rootDir, overrides = {}) {
files: [
'scripts/observability-readiness.js',
'scripts/operator-readiness-dashboard.js',
'scripts/platform-audit.js'
'scripts/platform-audit.js',
'scripts/preview-pack-smoke.js'
],
scripts: {
'discussion:audit': 'node scripts/discussion-audit.js',
'observability:ready': 'node scripts/observability-readiness.js',
'operator:dashboard': 'node scripts/operator-readiness-dashboard.js',
'platform:audit': 'node scripts/platform-audit.js',
'preview-pack:smoke': 'node scripts/preview-pack-smoke.js',
'security:ioc-scan': 'node scripts/ci/scan-supply-chain-iocs.js',
'security:advisory-sources': 'node scripts/ci/supply-chain-advisory-sources.js'
}
}, null, 2),
'scripts/operator-readiness-dashboard.js': 'operator dashboard generator',
'scripts/preview-pack-smoke.js': [
'ecc.preview-pack-smoke.v1',
'preview-pack-artifacts-present',
'hermes-boundary-sanitized',
'publication-blockers-preserved'
].join('\n'),
'docs/ECC-2.0-GA-ROADMAP.md': [
'https://linear.app/itomarkets/project/ecc-platform-roadmap-52b328ee03e1',
'Linear ITO-44 ITO-59',
@@ -51,12 +59,23 @@ function seedRepo(rootDir, overrides = {}) {
'AgentShield Enterprise Iteration',
'ECC-Tools PR #78',
'hosted promotion',
'operator-visible promotion output values',
'hosted promotion judge audit traces',
'package-manager hardening Action outputs',
'production Marketplace readback state',
'eb69412',
'announcementGate',
'ITO-55'
'ITO-55',
'Linear live sync is current for the May 17 merge batch',
'operator progress snapshot'
].join('\n'),
'docs/releases/2.0.0-rc.1/publication-readiness.md': 'Claude plugin Codex plugin',
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md': 'Claude plugin Codex plugin npm package Publication Paths',
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': 'publication-readiness.md release-notes.md quickstart.md',
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': [
'publication-readiness.md release-notes.md quickstart.md',
'`scripts/preview-pack-smoke.js`',
'npm run preview-pack:smoke'
].join('\n'),
'docs/releases/2.0.0-rc.1/release-notes.md': 'release notes',
'docs/releases/2.0.0-rc.1/x-thread.md': 'x thread',
'docs/releases/2.0.0-rc.1/linkedin-post.md': 'linkedin post',
@@ -70,10 +89,34 @@ function seedRepo(rootDir, overrides = {}) {
'PR queue',
'Not complete'
].join('\n'),
'docs/HERMES-SETUP.md': 'Hermes setup',
'skills/hermes-imports/SKILL.md': 'Hermes imports',
'docs/stale-pr-salvage-ledger.md': 'Manual review tail',
'docs/architecture/progress-sync-contract.md': 'GitHub PRs/issues/discussions Linear project local handoff repo roadmap scripts/work-items.js',
'docs/HERMES-SETUP.md': 'Hermes setup Public Release Candidate Scope',
'skills/hermes-imports/SKILL.md': 'Hermes imports Sanitization Checklist Do not ship raw workspace exports Output Contract',
'docs/stale-pr-salvage-ledger.md': [
'Remaining Manual-Review Backlog',
'Linear ITO-55',
'#1687 zh-CN localization tail',
'#1609 Persian README translation',
'#1563 zh-TW README sync',
'#1564 Turkish README sync',
'#1565 pt-BR README sync',
'not a release-blocking salvage task'
].join('\n'),
'docs/legacy-artifact-inventory.md': [
'Translator/manual review',
'ITO-55',
'#1687 zh-CN localization tail',
'#1609 Persian README translation',
'#1563 zh-TW README sync',
'#1564 Turkish README sync',
'#1565 pt-BR README sync',
'no automatic import remains release-blocking'
].join('\n'),
'docs/architecture/progress-sync-contract.md': [
'GitHub PRs/issues/discussions Linear project local handoff repo roadmap scripts/work-items.js',
'node scripts/work-items.js sync-github --repo <owner/repo>',
'node scripts/status.js --json',
'Linear remains the external status surface'
].join('\n'),
'docs/architecture/observability-readiness.md': 'observability-readiness.js',
'docs/security/supply-chain-incident-response.md': 'TanStack Mini Shai-Hulud node-ipc scan-supply-chain-iocs.js supply-chain-advisory-sources.js',
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md': 'TanStack Mini Shai-Hulud Node IPC follow-up node-ipc IOC scan',
@@ -187,12 +230,123 @@ function runTests() {
assert.strictEqual(report.ready, false);
assert.strictEqual(report.publicationReady, false);
assert.ok(report.requirements.some(item => item.id === 'completion-dashboard' && item.status === 'complete'));
assert.ok(report.requirements.some(item => (
item.id === 'ecc-preview-pack'
&& item.status === 'current'
&& item.evidence.includes('deterministic smoke gate')
&& item.gap === 'repeat clean-checkout preview-pack smoke before publication'
)));
assert.ok(report.requirements.some(item => (
item.id === 'hermes-specialized-skills'
&& item.status === 'current'
&& item.evidence.includes('covered by preview-pack smoke')
&& item.gap === 'repeat preview-pack smoke before release review'
)));
assert.ok(report.requirements.some(item => item.id === 'ecc-tools-next-level' && item.status === 'in_progress'));
assert.ok(report.requirements.some(item => (
item.id === 'agentshield-enterprise-iteration'
&& item.gap === 'workflow automation around protected rollout and richer runtime review UX pending after policy promotion shipped'
&& item.gap === 'deepen live operator approval/readback after Marketplace/payment gates'
&& item.evidence.includes('policy-promotion Action outputs')
&& item.evidence.includes('hosted promotion judge audit traces')
)));
assert.ok(report.requirements.some(item => (
item.id === 'ecc-tools-next-level'
&& item.gap === 'complete Marketplace purchase/webhook readback, then run the live announcement gate'
&& item.evidence.includes('operator-visible promotion output details')
&& item.evidence.includes('hosted promotion judge audit traces')
&& item.evidence.includes('billing announcement preflight')
&& item.evidence.includes('production KV readback state')
)));
assert.ok(report.requirements.some(item => (
item.id === 'supply-chain-local-protection'
&& item.artifact.includes('AgentShield package-manager hardening')
&& item.evidence.includes('known AI-tool persistence IOCs')
&& item.evidence.includes('unsupported npm age-key drift')
&& item.gap === 'repeat advisory/source refresh and Linear sync after each significant supply-chain batch'
)));
assert.ok(report.requirements.some(item => (
item.id === 'legacy-salvage'
&& item.status === 'current'
&& item.evidence.includes('all localization tails are attached to Linear ITO-55')
&& item.gap === 'repeat legacy scan before release'
)));
assert.ok(report.requirements.some(item => (
item.id === 'linear-roadmap-and-progress'
&& item.status === 'current'
&& item.evidence.includes('Linear live sync')
&& item.gap === 'repeat Linear/project status update and local work-items sync after each significant merge batch'
)));
assert.ok(report.top_actions.some(item => item.id === 'naming-and-plugin-publication'));
assert.ok(!report.top_actions.some(item => item.id === 'ecc-preview-pack'));
assert.ok(!report.top_actions.some(item => item.id === 'hermes-specialized-skills'));
assert.ok(!report.top_actions.some(item => item.id === 'legacy-salvage'));
assert.ok(!report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('Linear progress stays in progress until live sync evidence is mirrored', () => {
const rootDir = createTempDir('operator-dashboard-linear-progress-');
try {
seedRepo(rootDir, {
'docs/ECC-2.0-GA-ROADMAP.md': [
'https://linear.app/itomarkets/project/ecc-platform-roadmap-52b328ee03e1',
'Linear ITO-44 ITO-59',
'AgentShield Enterprise Iteration',
'ECC-Tools PR #78',
'hosted promotion',
'announcementGate',
'ITO-55'
].join('\n')
});
const report = buildSeededReport(rootDir);
const linearProgress = report.requirements.find(item => item.id === 'linear-roadmap-and-progress');
assert.strictEqual(linearProgress.status, 'in_progress');
assert.strictEqual(linearProgress.evidence, 'repo mirror and progress-sync contract are present');
assert.strictEqual(linearProgress.gap, 'recurring Linear status sync and productized realtime sync remain pending');
assert.ok(report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('preview pack and Hermes gates stay in progress until smoke gate is wired', () => {
const rootDir = createTempDir('operator-dashboard-preview-smoke-');
try {
seedRepo(rootDir, {
'package.json': JSON.stringify({
files: [
'scripts/observability-readiness.js',
'scripts/operator-readiness-dashboard.js',
'scripts/platform-audit.js'
],
scripts: {
'discussion:audit': 'node scripts/discussion-audit.js',
'observability:ready': 'node scripts/observability-readiness.js',
'operator:dashboard': 'node scripts/operator-readiness-dashboard.js',
'platform:audit': 'node scripts/platform-audit.js',
'security:ioc-scan': 'node scripts/ci/scan-supply-chain-iocs.js',
'security:advisory-sources': 'node scripts/ci/supply-chain-advisory-sources.js'
}
}, null, 2),
'scripts/preview-pack-smoke.js': null,
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': 'publication-readiness.md release-notes.md quickstart.md'
});
const report = buildSeededReport(rootDir);
const previewPack = report.requirements.find(item => item.id === 'ecc-preview-pack');
const hermes = report.requirements.find(item => item.id === 'hermes-specialized-skills');
assert.strictEqual(previewPack.status, 'in_progress');
assert.strictEqual(previewPack.gap, 'final clean-checkout release approval and publish evidence still pending');
assert.strictEqual(hermes.status, 'in_progress');
assert.strictEqual(hermes.gap, 'final preview-pack smoke and release review pending');
assert.ok(report.top_actions.some(item => item.id === 'ecc-preview-pack'));
assert.ok(report.top_actions.some(item => item.id === 'hermes-specialized-skills'));
} finally {
cleanup(rootDir);
}
@@ -216,6 +370,10 @@ function runTests() {
marker: 'checksum-verified policy promotion',
gap: 'workflow automation around protected rollout and richer runtime review UX pending after policy promotion shipped'
},
{
marker: 'hosted promotion judge audit traces',
gap: 'deepen live operator approval/readback after Marketplace/payment gates'
},
{
marker: '#78-#91',
gap: 'workflow automation plus policy promotion/review UX pending after policy export shipped'
+260
View File
@@ -0,0 +1,260 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { execFileSync, spawnSync } = require('child_process');
const SCRIPT = path.join(__dirname, '..', '..', 'scripts', 'preview-pack-smoke.js');
const {
REQUIRED_ARTIFACTS,
REQUIRED_PUBLICATION_BLOCKERS,
REQUIRED_VERIFICATION_COMMANDS,
buildReport,
parseArgs,
renderText,
} = require(SCRIPT);
const RELEASE_DIR = 'docs/releases/2.0.0-rc.1';
function createTempDir(prefix) {
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
}
function cleanup(dirPath) {
fs.rmSync(dirPath, { recursive: true, force: true });
}
function writeFile(rootDir, relativePath, content) {
const targetPath = path.join(rootDir, relativePath);
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
fs.writeFileSync(targetPath, content);
}
function manifestContent() {
return [
'# ECC v2.0.0-rc.1 Preview Pack Manifest',
'',
'## Pack Contents',
'',
'| Artifact | Role | Gate |',
'| --- | --- | --- |',
...REQUIRED_ARTIFACTS.map(artifact => `| \`${artifact}\` | release artifact | checked |`),
'',
'## Hermes Skill Boundary',
'',
'- no raw workspace exports;',
'',
'## Final Verification Commands',
'',
'```bash',
...REQUIRED_VERIFICATION_COMMANDS,
'```',
'',
'## Publication Blockers',
'',
...REQUIRED_PUBLICATION_BLOCKERS.map(blocker => `- ${blocker}`),
'',
'The preview pack is not public without approval-gated release, package, plugin, and announcement steps.',
].join('\n');
}
function seedRepo(rootDir, overrides = {}) {
const files = {
'package.json': JSON.stringify({
files: ['scripts/preview-pack-smoke.js'],
scripts: {
'preview-pack:smoke': 'node scripts/preview-pack-smoke.js',
},
}, null, 2),
'scripts/preview-pack-smoke.js': 'preview pack smoke script',
[`${RELEASE_DIR}/preview-pack-manifest.md`]: manifestContent(),
'docs/HERMES-SETUP.md': [
'# Hermes Setup',
'Public Release Candidate Scope',
'ECC v2.0.0-rc.1 documents the Hermes surface',
'No raw workspace export is included.',
].join('\n'),
'skills/hermes-imports/SKILL.md': [
'---',
'name: hermes-imports',
'---',
'Sanitization Checklist',
'Do not ship raw workspace exports',
'Output Contract',
].join('\n'),
};
for (const artifact of REQUIRED_ARTIFACTS) {
if (!Object.prototype.hasOwnProperty.call(files, artifact)) {
files[artifact] = `${artifact} public preview-pack content`;
}
}
for (const [relativePath, content] of Object.entries({ ...files, ...overrides })) {
if (content === null) {
continue;
}
writeFile(rootDir, relativePath, content);
}
}
function run(args = [], options = {}) {
return execFileSync('node', [SCRIPT, ...args], {
cwd: options.cwd || path.join(__dirname, '..', '..'),
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe'],
timeout: 10000,
});
}
function runProcess(args = [], options = {}) {
return spawnSync('node', [SCRIPT, ...args], {
cwd: options.cwd || path.join(__dirname, '..', '..'),
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe'],
timeout: 10000,
});
}
function test(name, fn) {
try {
fn();
console.log(` PASS ${name}`);
return true;
} catch (error) {
console.log(` FAIL ${name}`);
console.log(` Error: ${error.message}`);
return false;
}
}
function runTests() {
console.log('\n=== Testing preview-pack-smoke.js ===\n');
let passed = 0;
let failed = 0;
if (test('parseArgs accepts smoke flags and rejects invalid values', () => {
const rootDir = createTempDir('preview-pack-smoke-args-');
try {
const parsed = parseArgs([
'node',
'script',
'--format=json',
`--root=${rootDir}`,
]);
assert.strictEqual(parsed.format, 'json');
assert.strictEqual(parsed.root, path.resolve(rootDir));
assert.throws(() => parseArgs(['node', 'script', '--format', 'xml']), /Invalid format/);
assert.throws(() => parseArgs(['node', 'script', '--root']), /--root requires a value/);
assert.throws(() => parseArgs(['node', 'script', '--unknown']), /Unknown argument/);
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('seeded release pack passes every smoke check', () => {
const rootDir = createTempDir('preview-pack-smoke-pass-');
try {
seedRepo(rootDir);
const report = buildReport({ root: rootDir });
assert.strictEqual(report.schema_version, 'ecc.preview-pack-smoke.v1');
assert.strictEqual(report.ready, true);
assert.strictEqual(report.summary.failed, 0);
assert.ok(report.checks.every(check => check.status === 'pass'));
const text = renderText(report);
assert.ok(text.includes('Ready: yes'));
assert.ok(text.includes('Passed: 5'));
assert.ok(text.includes('Failed: 0'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('script registration fails closed without package wiring', () => {
const rootDir = createTempDir('preview-pack-smoke-package-');
try {
seedRepo(rootDir, {
'package.json': JSON.stringify({ files: [], scripts: {} }, null, 2),
});
const report = buildReport({ root: rootDir });
const registration = report.checks.find(check => check.id === 'preview-pack-script-registered');
assert.strictEqual(report.ready, false);
assert.strictEqual(registration.status, 'fail');
assert.ok(registration.fix.includes('preview-pack:smoke'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('Hermes boundary fails closed on private local paths', () => {
const rootDir = createTempDir('preview-pack-smoke-private-path-');
try {
seedRepo(rootDir, {
[`${RELEASE_DIR}/quickstart.md`]: 'Do not ship /Users/affoon/private-state in public docs.',
});
const report = buildReport({ root: rootDir });
const boundary = report.checks.find(check => check.id === 'hermes-boundary-sanitized');
assert.strictEqual(report.ready, false);
assert.strictEqual(boundary.status, 'fail');
assert.ok(boundary.evidence.includes(`${RELEASE_DIR}/quickstart.md:1`));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('CLI emits json and uses status 2 for failed smoke reports', () => {
const rootDir = createTempDir('preview-pack-smoke-cli-');
try {
seedRepo(rootDir);
const stdout = run(['--format=json', `--root=${rootDir}`], { cwd: rootDir });
const parsed = JSON.parse(stdout);
assert.strictEqual(parsed.ready, true);
writeFile(rootDir, 'package.json', JSON.stringify({ files: [], scripts: {} }, null, 2));
const failedRun = runProcess(['--format=json', `--root=${rootDir}`], { cwd: rootDir });
assert.strictEqual(failedRun.status, 2);
assert.strictEqual(failedRun.stderr, '');
assert.ok(failedRun.stdout.includes('"ready": false'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('CLI help exits successfully and invalid flags fail before reporting', () => {
const help = runProcess(['--help']);
assert.strictEqual(help.status, 0);
assert.strictEqual(help.stderr, '');
assert.ok(help.stdout.includes('Usage: node scripts/preview-pack-smoke.js'));
const invalid = runProcess(['--format=xml']);
assert.strictEqual(invalid.status, 1);
assert.strictEqual(invalid.stdout, '');
assert.match(invalid.stderr, /Error: Invalid format/);
})) passed++; else failed++;
console.log(`\nPassed: ${passed}`);
console.log(`Failed: ${failed}`);
if (failed > 0) {
process.exit(1);
}
}
if (require.main === module) {
runTests();
}