diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..52e66f6 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,36 @@ +## Summary + + + +## Linked issue + +Closes # + +## Contribution receipt + +- Scope class: docs_only | static_fixture | local_lab | ctf_range | authorized_live +- Target authority: +- Network use: none | loopback | private_lab | authorized_external +- Claims or evidence changed: +- Redaction/provenance notes: + +## Verification + +- [ ] `npm run typecheck` +- [ ] `npm test` +- [ ] `npm run doctor` +- [ ] Risk-specific checks are listed below, or not applicable with a reason + +Exact commands and results: + +## Risk and rollback + +- Residual risk: +- Rollback: + +## Delivery checks + +- [ ] Diff is scoped against current `upstream/main` +- [ ] No unrelated protected evidence, safety tests, or provider/config files were removed +- [ ] Published review history was not force-pushed +- [ ] Exact-head CI must be green before merge diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27ec232..fe0869b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,13 +2,24 @@ name: T3MP3ST CI on: pull_request: + branches: [main] push: branches: - main + tags: + - "v*" + +permissions: + contents: read + +concurrency: + group: t3mp3st-ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: test: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 @@ -35,3 +46,35 @@ jobs: # Non-network smoke: core traps run deterministically; server/live tiers # auto-skip when no server/LLM is present (they are absent in CI). - run: npm run smoke + + release: + if: startsWith(github.ref, 'refs/tags/v') + needs: test + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + ref: ${{ github.sha }} + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22 + cache: npm + - run: npm ci + - run: npm run test:release + - run: npm audit --audit-level=high + - run: npm run pack:dry-run + - run: npm pack --json > pack-result.json + - name: Record release checksums + run: | + package_file="$(node -e "const fs=require('fs'); const p=JSON.parse(fs.readFileSync('pack-result.json')); process.stdout.write(p[0].filename)")" + sha256sum "$package_file" > SHA256SUMS + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: tested-package-${{ github.sha }} + path: | + *.tgz + SHA256SUMS + pack-result.json + if-no-files-found: error + retention-days: 14 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8018034..d2e1ef2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,12 @@ T3MP3ST needs contributions from prompt engineers, cyber operators, bug bounty h The best contributions make the system more capable while making its evidence and authority boundaries clearer. +The canonical repository and tracker are +[`elder-plinius/T3MP3ST`](https://github.com/elder-plinius/T3MP3ST). Open issues +and pull requests there against `main`. The project uses focused branches, +squash merges, green exact-head CI, and does not permit force-pushing published +review history. + ## High-Value Contribution Types - Add a tool adapter in `src/arsenal/catalog.ts`. @@ -41,6 +47,12 @@ Prompt packs should include: ## Review Standard +Behavior changes must include outcome-oriented regression coverage. A change +with no relevant tests is blocked. Changed executable lines should reach at +least 50% coverage; documentation-only and metadata-only changes may mark this +not applicable with a reason. Trust-boundary, scope, evidence, provider, +installation, and release changes also need the focused checks for that risk. + Before opening a PR: ```bash @@ -72,6 +84,14 @@ unrelated provider/config churn, benchmark fixture removals, provenance doc removals, or safety-test removals. If the branch has drifted, recreate it from current `main` and reapply only the intended change. +Maintainers run `npm run test:release`, `npm audit --audit-level=high`, and the +package dry run against the exact release commit before publishing. A green PR +gate is necessary for review and merge, but it is not release certification. + +Do not include secrets, private tracker content, unlicensed corpora, or +uncoordinated vulnerability details. Use the disclosure channel in +`SECURITY.md` for security-sensitive reports. + ## Style - Prefer clear adapters and evidence contracts over clever hidden behavior. diff --git a/docs/PULL_REQUEST_DELIVERY.md b/docs/PULL_REQUEST_DELIVERY.md index ed3696d..334cfad 100644 --- a/docs/PULL_REQUEST_DELIVERY.md +++ b/docs/PULL_REQUEST_DELIVERY.md @@ -72,6 +72,14 @@ both human contributors and coding agents. - screenshots or artifacts for UI/reporting changes - residual risk or follow-up work +7. Preserve review identity and history. + + Sign contributor commits with a key associated with your forge identity (or + GitHub's verified web flow). Do not force-push a published review branch; + add corrective commits. Maintainers recheck the exact head, required CI, + mergeability, and linked issues immediately before the configured squash + merge. + ## Coding-Agent Instructions When an agent prepares a PR, it must perform a final scope audit before posting. @@ -139,3 +147,10 @@ feature details while stale-base deletions remain in the diff. Only comment on PRs that need action: concrete fixes, missing verification, missing receipts, or a rebase/scope cleanup. Ready PRs should not receive process comments. + +When a contributor has substantially completed a significant reviewed change +and only narrow mechanical cleanup remains, maintainers may resolve the small +conflict, preserve an established default, or add focused regression coverage +as a courtesy. Re-run the full exact-head review and tests and tell the +contributor what changed. Large rebases, behavior changes, architectural +judgment, or newly discovered substantive defects remain contributor work. diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 3540b85..fd82ad4 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -19,6 +19,7 @@ npm run test:no-self-fitting npm run test:no-phantom-tools npm run test:gate npm run prompt:audit +npm run pack:dry-run # inspect the allowlisted package manifest; no workspace/private files ``` ## 2. Local API smoke (loopback only) @@ -56,8 +57,22 @@ degrade gracefully — they never fail the core run. ## 6. Publish +- Confirm the release commit is already on `main`, CI is green at that exact + SHA, the version and changelog agree, and the tag is signed and points to that + commit. Never move or reuse a failed release tag; correct the release and use + a new version/tag. - Verify `repository.url` in `package.json` points at this repo. To retarget it: ```bash npm pkg set repository.url="git+https://github.com//.git" ``` - Tag the release only after Sections 1–2 are green. +- Push the `v*` tag and wait for the tag workflow. It reruns + `npm run test:release`, the high-severity dependency audit, and the package + dry run against the exact tag, then retains the tested `.tgz`, its manifest, + and `SHA256SUMS` as workflow artifacts. +- Inspect `pack-result.json`: only the allowlisted runtime, scripts, tools, + documentation, examples, and package metadata may ship. Workspace notes, + tests, AIWG/provider deployment internals, secrets, and local artifacts are + release blockers. +- Publish the retained, checksum-matched package artifact. Do not rebuild a + different archive from another checkout after certification. diff --git a/docsite/t3mp3st-docs/content/PULL_REQUEST_DELIVERY.md b/docsite/t3mp3st-docs/content/PULL_REQUEST_DELIVERY.md index 933c4b0..0f3a6d1 100644 --- a/docsite/t3mp3st-docs/content/PULL_REQUEST_DELIVERY.md +++ b/docsite/t3mp3st-docs/content/PULL_REQUEST_DELIVERY.md @@ -83,6 +83,14 @@ both human contributors and coding agents. - screenshots or artifacts for UI/reporting changes - residual risk or follow-up work +7. Preserve review identity and history. + + Sign contributor commits with a key associated with your forge identity (or + GitHub's verified web flow). Do not force-push a published review branch; + add corrective commits. Maintainers recheck the exact head, required CI, + mergeability, and linked issues immediately before the configured squash + merge. + ## Coding-Agent Instructions When an agent prepares a PR, it must perform a final scope audit before posting. @@ -150,3 +158,10 @@ feature details while stale-base deletions remain in the diff. Only comment on PRs that need action: concrete fixes, missing verification, missing receipts, or a rebase/scope cleanup. Ready PRs should not receive process comments. + +When a contributor has substantially completed a significant reviewed change +and only narrow mechanical cleanup remains, maintainers may resolve the small +conflict, preserve an established default, or add focused regression coverage +as a courtesy. Re-run the full exact-head review and tests and tell the +contributor what changed. Large rebases, behavior changes, architectural +judgment, or newly discovered substantive defects remain contributor work. diff --git a/docsite/t3mp3st-docs/content/RELEASE_CHECKLIST.md b/docsite/t3mp3st-docs/content/RELEASE_CHECKLIST.md index 769a606..1f942c1 100644 --- a/docsite/t3mp3st-docs/content/RELEASE_CHECKLIST.md +++ b/docsite/t3mp3st-docs/content/RELEASE_CHECKLIST.md @@ -30,6 +30,7 @@ npm run test:no-self-fitting npm run test:no-phantom-tools npm run test:gate npm run prompt:audit +npm run pack:dry-run # inspect the allowlisted package manifest; no workspace/private files ``` ## 2. Local API smoke (loopback only) @@ -67,8 +68,22 @@ degrade gracefully — they never fail the core run. ## 6. Publish +- Confirm the release commit is already on `main`, CI is green at that exact + SHA, the version and changelog agree, and the tag is signed and points to that + commit. Never move or reuse a failed release tag; correct the release and use + a new version/tag. - Verify `repository.url` in `package.json` points at this repo. To retarget it: ```bash npm pkg set repository.url="git+https://github.com//.git" ``` - Tag the release only after Sections 1–2 are green. +- Push the `v*` tag and wait for the tag workflow. It reruns + `npm run test:release`, the high-severity dependency audit, and the package + dry run against the exact tag, then retains the tested `.tgz`, its manifest, + and `SHA256SUMS` as workflow artifacts. +- Inspect `pack-result.json`: only the allowlisted runtime, scripts, tools, + documentation, examples, and package metadata may ship. Workspace notes, + tests, AIWG/provider deployment internals, secrets, and local artifacts are + release blockers. +- Publish the retained, checksum-matched package artifact. Do not rebuild a + different archive from another checkout after certification. diff --git a/package-lock.json b/package-lock.json index 082ba73..8166662 100755 --- a/package-lock.json +++ b/package-lock.json @@ -3442,9 +3442,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", - "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", "funding": [ { "type": "github", @@ -3801,9 +3801,9 @@ } }, "node_modules/hono": { - "version": "4.12.27", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.27.tgz", - "integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==", + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.3.tgz", + "integrity": "sha512-r8AO2mYHoLxSHkgafNeC/BXyb2vWRxD3jem4Ts+ptav8oTG5FIRifAjuJEmZI4bSvvc2ns0GxmIYiZnHqN3mMw==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -4119,9 +4119,9 @@ } }, "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==", "license": "MIT", "engines": { "node": ">= 12" @@ -4260,9 +4260,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "funding": [ { @@ -4804,9 +4804,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -6018,9 +6018,9 @@ } }, "node_modules/undici": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.8.0.tgz", - "integrity": "sha512-ubshXMXwF3MQIMF1y/WxZdNBnjEKeSg2wF5mcGUtU55YTw34tnVVpKRlLf7ruDXZ5344KokPVX4RBx1wJm64Bw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.0.tgz", + "integrity": "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==", "license": "MIT", "engines": { "node": ">=22.19.0" diff --git a/package.json b/package.json index 4e5c5ec..054dd72 100755 --- a/package.json +++ b/package.json @@ -5,6 +5,17 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "type": "module", + "files": [ + "dist/", + "scripts/", + "tools/", + "docs/", + "examples/", + ".env.example", + "docker-compose.yml", + "index.ts", + "tsconfig.json" + ], "scripts": { "build": "tsc", "start": "node dist/cli.js", @@ -64,6 +75,8 @@ "mcp": "tsx src/mcp-server.ts", "mcp:prod": "node dist/mcp-server.js", "test": "vitest run src && node scripts/test-ops-preflight.mjs && node scripts/test-model-matrix.mjs && node scripts/refusal-frontier.mjs --self-test", + "test:release": "npm run lint && npm run typecheck && npm test && npm run test:coverage && npm run doctor && npm run verify-claims && npm run test:no-fitting && npm run test:no-self-fitting && npm run test:gate && npm run prompt:audit && npm run smoke && npm run build", + "pack:dry-run": "npm pack --dry-run", "test:coverage": "vitest run --coverage", "test:watch": "vitest src", "lint": "eslint src/**/*.ts", diff --git a/src/__tests__/local-agent-path-resolution.test.ts b/src/__tests__/local-agent-path-resolution.test.ts index 968e5dd..0ff3321 100644 --- a/src/__tests__/local-agent-path-resolution.test.ts +++ b/src/__tests__/local-agent-path-resolution.test.ts @@ -193,8 +193,9 @@ describe('detectLocalAgents — wiring: a well-known-dir CLI is reported install expect(claude?.installed).toBe(true); expect(claude?.path).toBe(claudePath); expect(claude?.version).toBe('1.2.3'); // parsed from the resolved binary's --version output - // codex/hermes are absent from this temp home → still not installed (no false positives). - expect(agents.find((a) => a.id === 'codex')?.installed).toBe(false); + // Do not assert that another real agent is absent: detection intentionally + // also scans system-wide install locations such as /usr/local/bin, so that + // result depends on the maintainer/CI host rather than this fixture. }); it('detects authenticated OpenCode and Oh My Pi installations (#136)', async () => {