{"_id":"@agenttool/xenia-surface","name":"@agenttool/xenia-surface","dist-tags":{"rc":"0.1.0-rc.1","latest":"0.1.0-rc.1"},"versions":{"0.1.0-rc.1":{"name":"@agenttool/xenia-surface","version":"0.1.0-rc.1","description":"Node checker and schemas for the XENIA Surface 0.1 candidate profile","type":"module","main":"./check.mjs","types":"./index.d.mts","license":"SEE LICENSE IN LICENSES.md","sideEffects":false,"engines":{"node":">=22"},"bin":{"xenia-surface-check":"check.mjs"},"exports":{".":{"types":"./index.d.mts","import":"./check.mjs","default":"./check.mjs"},"./manifest.schema.json":"./manifest.schema.json","./problem.schema.json":"./problem.schema.json","./result.schema.json":"./result.schema.json","./example-manifest.json":"./example-manifest.json","./package.json":"./package.json"},"scripts":{"test":"node --test *.test.mjs && npm run test:types","test:types":"tsc -p tsconfig.type-tests.json","pack:check":"npm pack --dry-run --json","prepack":"npm test"},"devDependencies":{"@types/node":"^24.13.3","ajv":"8.20.0","ajv-formats":"3.0.1","typescript":"~7.0.2"},"publishConfig":{"access":"public","provenance":true,"tag":"rc","registry":"https://registry.npmjs.org/"},"repository":{"type":"git","url":"git+https://github.com/cambridgetcg/xenia.git","directory":"surface/0.1"},"homepage":"https://github.com/cambridgetcg/xenia/tree/main/surface/0.1#readme","bugs":{"url":"https://github.com/cambridgetcg/xenia/issues"},"keywords":["agents","conformance","json-schema","xenia"],"xeniaSurface":{"profile":"xenia-surface/0.1","profileTag":"surface-v0.1.0-rc.1"},"gitHead":"c7bc8eebe1e500e02f2e17391ad40e3c854edc63","_id":"@agenttool/xenia-surface@0.1.0-rc.1","_nodeVersion":"24.18.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-NWxqG+oDWGOY4y8lTTYWruW3KVR5Qml3hh0QG4EFZr/AIDRQ+xucgiI5EIocRKSL0/pfMCqNNkXKhhJ9MF48Tw==","shasum":"ecf500afab8e66d30d624f0a8f2c31fdec87bf11","tarball":"https://registry.npmjs.org/@agenttool/xenia-surface/-/xenia-surface-0.1.0-rc.1.tgz","fileCount":12,"unpackedSize":113924,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@agenttool%2fxenia-surface@0.1.0-rc.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDpy+sisN33tpMdnVGsINGpIqRVZCTHoybTgUnXELnrZQIhAMhIsg56z8Y1meT+uhEmWztgLT72d8sbyOiHMGV0xd7G"}]},"_npmUser":{"name":"agenttool","email":"contact@cambridgetcg.com"},"directories":{},"maintainers":[{"name":"agenttool","email":"contact@cambridgetcg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/xenia-surface_0.1.0-rc.1_1783850921201_0.6742226410664676"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-12T10:08:41.014Z","0.1.0-rc.1":"2026-07-12T10:08:41.333Z","modified":"2026-07-12T10:08:41.709Z"},"maintainers":[{"name":"agenttool","email":"contact@cambridgetcg.com"}],"description":"Node checker and schemas for the XENIA Surface 0.1 candidate profile","homepage":"https://github.com/cambridgetcg/xenia/tree/main/surface/0.1#readme","keywords":["agents","conformance","json-schema","xenia"],"repository":{"type":"git","url":"git+https://github.com/cambridgetcg/xenia.git","directory":"surface/0.1"},"bugs":{"url":"https://github.com/cambridgetcg/xenia/issues"},"license":"SEE LICENSE IN LICENSES.md","readme":"# XENIA Surface 0.1\n\nStatus: **candidate profile**\n\nSurface 0.1 is the smallest part of XENIA that an unfamiliar agent can test\nfrom outside a service without credentials. It makes four things exact:\n\n1. where the machine manifest lives;\n2. how a bounded list of public GET resources negotiates JSON;\n3. how an unpredictable wrong route explains failure;\n4. how service claims distinguish assertion, test, and attestation.\n\nEverything else remains outside this profile. A Surface 0.1 pass is not proof\nof identity, authorization, consent, privacy, retention, continuity,\nportability, economic fairness, or the absence of rankings on untested routes.\n\nThe words **MUST**, **MUST NOT**, **SHOULD**, and **MAY** below name normative\nrequirements. A checker may report only what it observed.\n\n## 1. Discovery\n\nA service MUST publish a JSON manifest at:\n\n```text\n/.well-known/agent.json\n```\n\nThe response MUST:\n\n- return `200`;\n- use `application/json`;\n- match [manifest.schema.json](manifest.schema.json);\n- use `schema_version: xenia.surface.manifest/0.1`.\n\nPublic Surface URLs MUST use HTTPS. The checker permits plaintext HTTP only for\nloopback hosts so implementations can run local fixtures without pretending\nthat an unauthenticated public manifest is safe from network rewriting.\nURL strings MUST use lowercase `https://`, or `http://` with `localhost`, an\nIPv4 address in `127.0.0.0/8`, or `[::1]`. They MUST NOT embed user credentials.\nThe candidate schema URLs are pinned to tag `surface-v0.1.0-rc.1`. The project\nwill not move or reuse that tag; Git hosting does not make a tag physically\nimmutable, so this is a release policy as well as a URL choice.\n\n`/agent.txt` and `/.well-known/agent.txt` MAY remain as small compatibility\npointers. When present, they SHOULD contain the canonical JSON manifest URL.\nThey are not parsed for Surface 0.1 conformance.\n\n## 2. Representations\n\nThe manifest declares between one and eight same-origin public GET resources.\nResource IDs MUST be unique. Each `href` MUST omit queries and fragments, list\n`application/json`, and name a default media type from its own representations.\nThe checker tests every declared resource with this exact matrix:\n\n| `Accept` request | Required response |\n|---|---|\n| `application/json` | `2xx application/json` object with non-empty `schema_version` |\n| `text/html;q=0, application/json;q=1` | a JSON response with the same shape requirements |\n| `application/*;q=1, text/html;q=0.2` | a JSON response with the same shape requirements |\n| `*/*` | the declared default representation |\n| `text/html` | `2xx text/html` when declared; otherwise a `406` XENIA problem |\n| `application/json;q=0.2, text/html;q=1` | `2xx text/html`; sent only when HTML is declared |\n| `application/json;q=0, */*;q=1` | `2xx text/html` when declared; otherwise a `406` XENIA problem |\n| `application/x-xenia-unsupported` | a `406` XENIA problem |\n\nEvery response in the matrix MUST send `Vary: Accept`. Each JSON or problem\nbody MUST be valid UTF-8. A `406` problem MUST offer at least one action back\nto the same resource with method `GET` and one of its declared media types.\n\nThis matrix exercises quality values, wildcards, and an explicit `q=0`; a pass\ndoes not establish parser behavior for every possible `Accept` string. Surface\n0.1 does not separately probe a physically absent header because Node Fetch\nadds `*/*`, so it makes no claim about that unobserved wire case.\n\nThe checker does not infer anything about routes absent from `resources`.\n\n`?format=json` MAY exist as a convenience alias. It does not replace correct\n`Accept` handling.\n\n## 3. Problems\n\nThe checker generates a fresh, unadvertised same-origin route for every run. A\nGET to that path with `Accept: application/problem+json` MUST:\n\n- return `404`;\n- use `application/problem+json`;\n- send `Vary: Accept`;\n- match [problem.schema.json](problem.schema.json).\n\nA problem follows the HTTP Problem Details shape, adds a stable code, states\nwhether retrying unchanged may work, and links its documentation. It MUST\neither offer at least one typed `next_action` or explicitly set\n`terminal: true`, never both. Here, terminal means the service advertises no safe\nmachine-callable recovery for this response. It does not mean that recovery is\nimpossible forever.\n\nPassing this one probe does not establish that every error in the service has\nthe same shape. The checker reports the exact path it tested.\n\nThe generated route-not-found probe is never terminal. It MUST return exactly\none `discover` action pointing to `/.well-known/agent.json` with method `GET`\nand accept type `application/json`.\n\n## 4. Claims\n\nEvery entry in `manifest.claims` MUST name an `outcome` and one of three\nevidence states:\n\n- `asserted`: the service says this; no supporting test or attestation is\n  supplied;\n- `tested`: the service supplies metadata for a probe or audit it says observed\n  the scoped behavior;\n- `attested`: the service supplies metadata it labels as a signature or receipt\n  binding.\n\nThe outcome is `pass`, `fail`, or `unknown`. Evidence state and outcome are\nseparate axes; an attested report may still record a failed test.\n\n`tested` and `attested` claims MUST carry evidence. An attested claim MUST have\nat least one `signature` or `receipt` evidence item. Surface 0.1 does not define\nthe signed preimage, canonicalization, domain separation, key resolution, or\nreceipt verification protocol. It therefore does not establish that a declared\nbinding is cryptographically valid, or that the statement or inputs are true.\nVerified attestation belongs in a later cryptographic profile.\n\nClaim IDs MUST be unique. Every evidence expiry MUST be later than its\nobservation time. Evidence timestamps MUST use uppercase UTC form\n`YYYY-MM-DDTHH:mm:ss[.fraction]Z`.\n\nThe checker copies service claims into `declared_claims`. It creates separate\n`tested` claims from direct probes and never calls its unsigned output\n`attested`. It validates the shape of declared evidence metadata but does not\nfetch or cryptographically verify that evidence in Surface 0.1; both `tested`\nand `attested` labels in `declared_claims` remain service declarations.\n\nThe manifest MUST list important boundaries in `not_covered`. Silence is not a\nclaim of completion.\n\n## 5. Checker result\n\nRun the dependency-free checker with Node 22 or newer:\n\n```sh\nnode surface/0.1/check.mjs https://example.com\nnode surface/0.1/check.mjs https://example.com --json\n```\n\nThe JSON result matches [result.schema.json](result.schema.json) and records the\nexact method, URL, `Accept`, and `User-Agent` used for each observation:\n\n- `conformant`: every required observation passed;\n- `nonconformant`: at least one required observation definitely failed;\n- `indeterminate`: nothing definitely failed, but a timeout, network failure,\n  body limit, or dependent check prevented a complete observation.\n\nA result expires after 24 hours. It is a reproducible observation of the named\npublic GET scope, not a permanent badge.\n\nThe checker uses a 5-second request timeout, a 20-second total timeout, 65,536-byte\nlimits for manifests and problems, a 1,000,000-byte resource limit, no credentials, and\nno writes. Every result records the effective limits. It is intended as a local command. A hosted version needs its own\nprivate-network, redirect, DNS-rebinding, concurrency, and abuse boundaries.\n\nThe checker itself has no runtime dependency. Install the RC as a development\ntool and run it outside the service being observed:\n\n```sh\nnpm install --save-dev @agenttool/xenia-surface@rc\nnpx xenia-surface-check https://example.com --json\n```\n\nThe package also exposes the checker and hand validators to Node programs:\n\n```js\nimport { checkSurface, validateManifest } from \"@agenttool/xenia-surface\";\n```\n\nThe three schemas and example manifest have explicit JSON export paths, such\nas `@agenttool/xenia-surface/manifest.schema.json`. The npm release is the\ndistribution wrapper for the checker and profile pinned by the immutable\n`surface-v0.1.0-rc.1` Git tag; packaging does not move or replace those schema\nidentifiers.\n\nThis is a Node 22+ external checker, not a hosted scanning service or a Worker\nruntime library. A maximum-size manifest can require more outbound requests\nthan a Workers Free-plan invocation permits, and hosting it would require\nadditional private-network, redirect, DNS-rebinding, concurrency, and abuse\ncontrols. The service being checked may itself run on Cloudflare.\n\nThe test suite uses Ajv to cross-check emitted documents against the published\nJSON Schemas:\n\n```sh\nnpm install\nnpm test\n```\n\n## Files\n\n- [manifest.schema.json](manifest.schema.json): discovery contract\n- [problem.schema.json](problem.schema.json): structured refusal contract\n- [result.schema.json](result.schema.json): checker output contract\n- [example-manifest.json](example-manifest.json): smallest complete example\n- [check.mjs](check.mjs): executable external probe\n- [check.test.mjs](check.test.mjs): local fixtures for pass and failure cases\n","readmeFilename":"README.md","_rev":"1-895af16e74a65e39192143096c41c3b6"}