{"_id":"@drive9/drive9-dsh","name":"@drive9/drive9-dsh","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@drive9/drive9-dsh","version":"0.1.0","description":"Drive9 workspace and durable evidence components for DeepSeek Harness","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./filesystem":{"types":"./dist/filesystem.d.ts","default":"./dist/filesystem.js"},"./evidence":{"types":"./dist/evidence.d.ts","default":"./dist/evidence.js"},"./result-tools":{"types":"./dist/result-tools.d.ts","default":"./dist/result-tools.js"},"./runtime-context":{"types":"./dist/runtime-context.d.ts","default":"./dist/runtime-context.js"},"./cordis.patch.yml":"./cordis.patch.yml","./package.json":"./package.json"},"scripts":{"clean":"rm -rf dist coverage","build":"tsc -p tsconfig.build.json","check":"tsc -p tsconfig.json --noEmit","test":"vitest run","test:race":"vitest run --pool=forks --maxWorkers=4","test:real":"vitest run --config vitest.real.config.ts","lint:package":"publint","release:check":"bash scripts/release-public.sh --check","release:publish":"bash scripts/release-public.sh --publish","prepack":"npm run clean && npm run build"},"engines":{"node":">=22.19.0"},"publishConfig":{"access":"public"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/drive9-ai/drive9-dsh.git"},"homepage":"https://github.com/drive9-ai/drive9-dsh#readme","bugs":{"url":"https://github.com/drive9-ai/drive9-dsh/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"keywords":["deepseek","agent","harness","dsh-plugin","workspace","evidence"],"dependencies":{"@deepseek-ai/schemastery":"3.18.1","drive9":"0.1.4"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-fs":"^0.1.0-rc.6","@deepseek-ai/dsh-llm":"^0.1.0-rc.6","@deepseek-ai/dsh-sandbox":"^0.1.0-rc.6","@deepseek-ai/dsh-sandbox-policy":"^0.1.0-rc.6","@deepseek-ai/dsh-session":"^0.1.0-rc.6","@deepseek-ai/dsh-spill":"^0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"^0.1.0-rc.6","@deepseek-ai/dsh-tools":"^0.1.0-rc.6"},"devDependencies":{"@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-agent":"0.1.0-rc.6","@deepseek-ai/dsh-agent-loop":"0.1.0-rc.6","@deepseek-ai/dsh-agent-loop-testkit":"0.1.0-rc.6","@deepseek-ai/dsh-fs":"0.1.0-rc.6","@deepseek-ai/dsh-fs-observation-policy":"0.1.0-rc.6","@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-output-retention":"0.1.0-rc.6","@deepseek-ai/dsh-sandbox":"0.1.0-rc.6","@deepseek-ai/dsh-sandbox-policy":"0.1.0-rc.6","@deepseek-ai/dsh-session":"0.1.0-rc.6","@deepseek-ai/dsh-spill":"0.1.0-rc.6","@deepseek-ai/dsh-spill-policy":"0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"0.1.0-rc.6","@deepseek-ai/dsh-tool-fs":"0.1.0-rc.6","@deepseek-ai/dsh-tools":"0.1.0-rc.6","@types/node":"24.12.4","publint":"0.3.21","tsx":"4.22.1","typescript":"5.9.3","vitest":"3.2.7"},"gitHead":"1137ecb6da1984353adf0332cba98253b438c378","_id":"@drive9/drive9-dsh@0.1.0","_nodeVersion":"25.8.2","_npmVersion":"11.11.1","dist":{"integrity":"sha512-iGrxlGTqfCU7ZjQwKQqUJGYYnlVwWoLwIE7NmsATSoIpYlpC/ldie5TI438hr1zBT+qdigHaXttQ5uMBCwoI5Q==","shasum":"5a1846460e7490ffb6e01d7bb806410568aacd36","tarball":"https://registry.npmjs.org/@drive9/drive9-dsh/-/drive9-dsh-0.1.0.tgz","fileCount":57,"unpackedSize":244154,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAZMZimxXNom5dvBeNv3R2wosQQTjCjzqSnggmXgBaB5AiEA6cjWBsiF837rLbmvm87vih5QAoW9oLq0c60/PZwBULw="}]},"_npmUser":{"name":"qiffang","email":"qiffang33@gmail.com"},"directories":{},"maintainers":[{"name":"qiffang","email":"qiffang33@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/drive9-dsh_0.1.0_1786730373705_0.3956014080587509"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-14T17:59:33.546Z","0.1.0":"2026-08-14T17:59:33.850Z","modified":"2026-08-14T17:59:34.078Z"},"maintainers":[{"name":"qiffang","email":"qiffang33@gmail.com"}],"description":"Drive9 workspace and durable evidence components for DeepSeek Harness","homepage":"https://github.com/drive9-ai/drive9-dsh#readme","keywords":["deepseek","agent","harness","dsh-plugin","workspace","evidence"],"repository":{"type":"git","url":"git+https://github.com/drive9-ai/drive9-dsh.git"},"bugs":{"url":"https://github.com/drive9-ai/drive9-dsh/issues"},"license":"Apache-2.0","readme":"# Drive9 for DeepSeek Harness\n\nPersistent agent workspaces and durable, bounded tool evidence for\n[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).\n\n`@drive9/drive9-dsh` is a standard DSH bundle with four independent Cordis components:\n\n- a Drive9 revision-CAS filesystem for Harness `read`, `write`, and `edit` tools;\n- an isolated evidence backend for oversized tool results;\n- model-visible `result_search` and `result_read` tools with hard output limits;\n- a model-visible runtime-context warning for the opt-in eventual mount profile.\n\nThe architecture keeps four lifecycles separate:\n\n| Layer | Owner |\n| --- | --- |\n| Agent loop | DeepSeek Harness |\n| Session and conversation history | DeepSeek Harness |\n| Persistent workspace and immutable evidence | Drive9 |\n| Shell, sandbox, language servers, and compute runtime | the user's DSH deployment |\n\nThe Drive9 mount only exposes the persistent workspace inside an existing runtime.\nIt does not create, own, or keep that runtime alive. Evidence remains readable after\nthe runtime or workspace disappears because it is stored under a separate, unmounted\nDrive9 root.\n\nDrive9 does **not** provide a shell or sandbox. V1 exposes two explicit mount-consistency\nprofiles:\n\n- `strong` (default and recommended) uses a Linux Drive9 FUSE mount in the same\n  execution world as Harness process tools. Startup proves SDK-to-mount and\n  mount-to-SDK coherence, and writes wait for exact mounted bytes before returning.\n- `eventual` is an opt-in WebDAV profile. Model-facing reads, writes, revision CAS, and\n  evidence still use the Drive9 SDK, but process tools may observe stale mounted bytes\n  for more than 30 seconds after an SDK write.\n\nThe integration never silently downgrades `strong` to `eventual`. In real macOS\nWebDAVFS validation, the Drive9 bridge observed an SDK write immediately while the\nmounted `open`/`stat` view remained stale or blocked for more than 30 seconds.\n\n## Why\n\nAgent work has two different kinds of state:\n\n```text\nmodel filesystem tools ── Drive9 SDK + revision CAS ── persistent workspace\n                                  │\nprocess tools ── /mnt/drive9 ─────┘\n\nlarge tool output ── isolated Drive9 evidence root ── exact result_id\n                                                   ├─ result_search\n                                                   └─ result_read\n```\n\nThe workspace remains process-visible, while evidence stays outside the workspace\nmount. A shell command, workspace deletion, or workspace rollback cannot address the\nevidence namespace.\n\n## Prerequisites\n\n- Linux with Node.js 22.19 or newer, npm, and pnpm on `PATH`;\n- DeepSeek Harness `0.1.0-rc.6`, including the standard `dsh` CLI;\n- a current Drive9 CLI with `drive9 token issue` support and access to a Drive9\n  server;\n- `/dev/fuse` and `fusermount3` for the recommended `strong` profile, or a WebDAV\n  mount for the opt-in `eventual` profile;\n- separate, path-scoped workspace and evidence credentials. An owner credential is\n  needed only to create roots and issue those scoped credentials.\n\nInstall the Harness CLI and pnpm before continuing:\n\n```bash\nnpm install --global @deepseek-ai/dsh@0.1.0-rc.6 pnpm\n```\n\nInstall the Drive9 CLI from the\n[public Drive9 repository](https://github.com/mem9-ai/drive9) and verify both CLIs:\n\n```bash\ndsh --version\ndrive9 version\n```\n\n## Quick start\n\nSupply the owner credential through your normal secret injector, then configure the\nnon-secret paths once. The assertion fails before provisioning if the secret is\nabsent:\n\n```bash\n: \"${DRIVE9_OWNER_API_KEY:?inject the Drive9 owner credential}\"\n\nexport DRIVE9_BASE_URL=\"https://api.drive9.ai\"\nexport DRIVE9_EVIDENCE_BASE_URL=\"$DRIVE9_BASE_URL\"\nexport DRIVE9_MOUNT_ROOT=\"/mnt/drive9\"\nexport DRIVE9_REMOTE_ROOT=\"/workspace\"\nexport DRIVE9_EVIDENCE_ROOT=\"/evidence/dsh\"\nexport DRIVE9_MOUNT_CONSISTENCY=\"strong\"\n```\n\n### 1. Provision isolated roots and credentials\n\nCreate both roots once. Keep the evidence root unmounted so workspace tools and shell\ncommands cannot address it:\n\n```bash\ndrive9 ctx add \\\n  --name dsh-owner \\\n  --server \"$DRIVE9_BASE_URL\" \\\n  --api-key \"$DRIVE9_OWNER_API_KEY\"\ndrive9 ctx use dsh-owner\n\ndrive9 fs mkdir :/workspace\ndrive9 fs mkdir :/evidence/dsh\n\ndrive9 token issue dsh-workspace \\\n  --ttl 24h \\\n  --allow /workspace:read,list,write,delete \\\n  --print\n\ndrive9 token issue dsh-evidence \\\n  --ttl 24h \\\n  --allow /evidence/dsh:read,write \\\n  --print\n```\n\nEach command prints only the bearer token and saves its local name for later rotation\nor revocation. Store the printed value in your secret manager without leaving it on\ndisk, then inject the values as distinct credentials. The package rejects a shared\ncredential:\n\n```bash\n: \"${DRIVE9_WORKSPACE_API_KEY:?inject the workspace-scoped credential}\"\n: \"${DRIVE9_EVIDENCE_API_KEY:?inject the separate evidence-scoped credential}\"\n```\n\nSee [credential and deployment guidance](docs/operations.md) for production token\nscope, TTL, and rotation guidance.\n\n### 2. Mount the workspace\n\nMount the workspace into the Harness runtime. The default strong profile requires\nLinux with `/dev/fuse` and `fusermount3`:\n\n```bash\nmkdir -p \"$DRIVE9_MOUNT_ROOT\"\n\nDRIVE9_API_KEY=\"$DRIVE9_WORKSPACE_API_KEY\" \\\n  drive9 mount --mode=fuse --profile=none :/workspace \"$DRIVE9_MOUNT_ROOT\"\n```\n\nThe mount must exist in the **same execution world** as Harness subprocesses. If\nHarness runs inside a container, mount Drive9 inside that container or bind the mount\ninto it before Harness starts.\n\n`--profile=none` is part of the strong profile. A coding-agent mount profile can\nroute process paths through a local overlay while SDK calls still address Drive9,\nsplitting the two sides of the revision-CAS contract. Do not use a local-overlay\nprofile, and do not disable the startup proof to make one start.\n\nTo opt into relaxed WebDAV semantics instead, mount with WebDAV and explicitly select\n`eventual`:\n\n```bash\nDRIVE9_API_KEY=\"$DRIVE9_WORKSPACE_API_KEY\" \\\n  drive9 mount --mode=webdav --profile=none :/workspace \"$DRIVE9_MOUNT_ROOT\"\n\nexport DRIVE9_MOUNT_CONSISTENCY=\"eventual\"\n```\n\nThis profile returns from writes after the SDK CAS commits; it does not wait for the\nmounted path to converge. Do not use it for workflows that write through Harness and\nimmediately validate with `cat`, `rg`, tests, a language server, or another subprocess.\n\n### 3. Install the bundle\n\nThe recommended release channel is the prebuilt npm package:\n\n```bash\ndsh plugin --profile web add @drive9/drive9-dsh\n```\n\nTo validate an unreleased checkout or install before registry publication, build the\nsame prebuilt tarball from the public repository instead of installing the TypeScript\nsources directly from Git:\n\n```bash\ngit clone https://github.com/drive9-ai/drive9-dsh.git\ncd drive9-dsh\nnpm ci\nPACKAGE_TARBALL=\"$(npm pack --silent)\"\ndsh plugin --profile web add \"$PWD/$PACKAGE_TARBALL\"\ncd ..\n```\n\nThis source-build route runs the package's normal `prepack` build and gives DSH a\ntarball containing `dist/`. A direct `github:drive9-ai/drive9-dsh` dependency does not\ncontain built output and is not a supported install path.\n\nThe package declares a DSH bundle, so the standard `dsh plugin` command installs it\nand adds its `cordis.patch.yml` layer to the selected profile. The bundle disables the stock\n`fs-sandbox` and `spill-local` storage providers, then installs the Drive9 filesystem,\nevidence backend, and result tools. Harness's stock filesystem tools, subprocess\nruntime, sandbox policy, observation policy, and spill policy remain in place. The\nDrive9 filesystem implements the same per-call `read-only`, `workspace-write`, and\n`danger-full-access` mutation policy that the replaced filesystem provider enforced.\n\n### 4. Configure and run\n\n```bash\ncd \"$DRIVE9_MOUNT_ROOT\"\ndsh web --dump-config\ndsh web\n```\n\n`dsh web --dump-config` is the recommended preflight. Its composed tree must contain\nexactly one active `fs` provider: `@drive9/drive9-dsh/filesystem`. Custom profiles\nuse the equivalent `dsh --profile <name> --dump-config` and `dsh --profile <name>`\ncommands; no Drive9-specific launcher is required.\n\nTo remove the bundle and its profile layer:\n\n```bash\ndsh plugin --profile web remove @drive9/drive9-dsh\n```\n\nIn the default strong profile, startup fails instead of falling back or weakening the\ncontract when:\n\n- the mount is missing or not writable;\n- the remote root is missing or not a directory;\n- SDK writes do not appear through the mount;\n- mount writes do not produce a newer Drive9 revision through the SDK.\n\nThe eventual profile still validates the local mount directory and remote Drive9 root,\nlogs a prominent warning, adds the same warning to the model's durable runtime-context\nsnapshot, and skips the bidirectional proof by default. Explicitly setting\n`verifyCoherence: true` still runs the complete proof and propagates any failure.\n\n## Components\n\n### `@drive9/drive9-dsh/filesystem`\n\n`Drive9FileSystem` implements the complete Harness `FileSystem` contract.\n\n| Operation | Drive9 behavior |\n| --- | --- |\n| `resolve` | Canonical mount resolution with lexical and symlink escape rejection |\n| `processPath` / `fileUrl` | Authenticated provider targets mapped below the real mount |\n| `stat` | Drive9 metadata; revision becomes an opaque Harness version |\n| `readText` / `streamText` | Strict UTF-8, NUL rejection, no silent binary coercion |\n| `readBytes` | Metadata preflight plus bounded range read |\n| `listDir` | Stable sorting and `batchStat` requests capped at 256 paths |\n| guarded write/edit | Exact Drive9 revision CAS |\n| unconditional write/edit | Bounded read/modify/CAS retry |\n| mutation policy | DSH per-call sandbox policy, rechecked against the fresh canonical target |\n\nIn `strong`, ordinary success returns only after the SDK write commits and the mounted\npath exposes the same bytes. If Drive9 commits but the mount cannot be confirmed before\nthe bounded coherence deadline, the operation throws\n`DRIVE9_WORKSPACE_COMMITTED_MOUNT_UNCONFIRMED` with `workspaceCommitted: true`, the\ncommitted version, and reason `timeout`, `aborted`, or `io`. This is neither success nor\nevidence that the write did not happen; callers must inspect/reconcile rather than\nblindly retrying. In `eventual`, it returns after the SDK CAS succeeds; `processPath()` and\n`fileUrl()` remain available, but their mounted view has no read-your-writes guarantee.\nBoth methods reject targets not authenticated by that filesystem instance.\n\n### `@drive9/drive9-dsh/evidence`\n\n`Drive9EvidenceStore` implements Harness `SpillStore`:\n\n1. generate a random 256-bit capability;\n2. create the content object;\n3. create the canonical manifest with byte count and SHA-256;\n4. publish `result_id` and a provenance receipt only after both writes succeed.\n\nReads verify stable revisions, exact byte count, manifest shape, SHA-256, and strict\nUTF-8. A failed manifest write returns no locator. The unreachable content orphan can\nbe reclaimed by operator retention without exposing partial evidence to the model.\n\n### `@drive9/drive9-dsh/result-tools`\n\nThe bundle registers:\n\n```text\nresult_search(result_id, query, max_matches?, context_lines?)\nresult_read(result_id, offset?, limit?)\n```\n\nBoth tools require an exact locator already issued into the current session's durable\ntool history, or inherited from its explicitly seeded direct parent. Guessing,\nenumeration, plain-text echoes, unseeded parent references, and sibling references are\ndenied.\n\nHard package limits:\n\n- 1,000 returned lines;\n- 64 KiB returned UTF-8 text;\n- 100 search matches;\n- 64 MiB scanned per request;\n- 64 KiB search query.\n\n## Configuration\n\nThe shipped bundle reads these environment variables:\n\n| Variable | Required | Default | Purpose |\n| --- | ---: | --- | --- |\n| `DRIVE9_BASE_URL` | no | Drive9 SDK default | Drive9 API base for workspace SDK calls |\n| `DRIVE9_WORKSPACE_API_KEY` | yes | — | Workspace-scoped SDK credential |\n| `DRIVE9_MOUNT_ROOT` | no | `/mnt/drive9` | Process-visible Drive9 mount |\n| `DRIVE9_REMOTE_ROOT` | no | `/` | Remote subtree represented by the mount |\n| `DRIVE9_MOUNT_CONSISTENCY` | no | `strong` | `strong` Linux FUSE or explicit `eventual` WebDAV semantics |\n| `DRIVE9_EVIDENCE_BASE_URL` | no | `DRIVE9_BASE_URL` | Drive9 API base for evidence |\n| `DRIVE9_EVIDENCE_API_KEY` | yes | — | Separate evidence-scoped credential |\n| `DRIVE9_EVIDENCE_ROOT` | no | `/evidence/dsh` | Unmounted evidence root |\n\nProgrammatic composition is also supported inside a DSH context that already provides\nthe standard `sandboxPolicy`, `systemPrompt`, and `tools` services:\n\n```ts\nimport { Context } from '@deepseek-ai/cordis'\nimport * as Drive9Dsh from '@drive9/drive9-dsh'\n\nconst ctx = new Context()\n\nawait ctx.plugin(Drive9Dsh, {\n  filesystem: {\n    mountRoot: '/mnt/drive9',\n    remoteRoot: '/workspace',\n    baseUrl: process.env.DRIVE9_BASE_URL,\n    apiKey: process.env.DRIVE9_WORKSPACE_API_KEY,\n    mountConsistency: 'strong',\n  },\n  evidence: {\n    root: '/evidence/dsh',\n    baseUrl: process.env.DRIVE9_BASE_URL,\n    apiKey: process.env.DRIVE9_EVIDENCE_API_KEY!,\n  },\n  resultTools: {\n    maxScanBytes: 16 * 1024 * 1024,\n  },\n})\n```\n\nThe preset rejects missing credentials and rejects using the same credential for\nworkspace and evidence.\n\n## Errors\n\nFilesystem failures use Harness `FS_*` codes, including `FS_STALE_VERSION`,\n`FS_NOT_OBSERVED`, `FS_PERMISSION_DENIED`, `FS_TOO_LARGE`, `FS_NOT_TEXT`,\n`FS_ABORTED`, and `FS_IO_ERROR`.\n\n`DRIVE9_WORKSPACE_COMMITTED_MOUNT_UNCONFIRMED` is the distinct post-commit outcome for\na strong-profile mount verification failure. It carries `workspaceCommitted: true` and\nmust never be treated as a retry-safe “write did not happen” error.\n\nEvidence retrieval uses stable `DRIVE9_RESULT_*` codes:\n\n- `DRIVE9_RESULT_INVALID_ID`\n- `DRIVE9_RESULT_NOT_FOUND`\n- `DRIVE9_RESULT_CORRUPT`\n- `DRIVE9_RESULT_UNAUTHORIZED`\n- `DRIVE9_RESULT_SCAN_LIMIT`\n- `DRIVE9_RESULT_ABORTED`\n- `DRIVE9_RESULT_IO`\n\nErrors never include credentials or authorization headers.\n\n## Security model\n\n- Workspace and evidence credentials must be distinct and path-scoped.\n- Evidence has no path, listing, mount, or filesystem-target API.\n- Locators are random capabilities but are not authorized by possession alone.\n- A versioned issuance receipt, immutable manifest, and enclosing Harness tool event\n  must agree on session, tool name, call id, locator, and manifest digest.\n- Current-session and explicitly seeded direct-parent evidence are readable; sibling\n  and unseeded artifacts are not.\n- V1 is append-only from the integration's perspective. Configure Drive9 retention or\n  administrative GC for the evidence root.\n\nSee [SECURITY.md](SECURITY.md) and the complete [V1 design lock](docs/design-lock.md).\n\n## Limits\n\nV1 intentionally does not provide:\n\n- a shell, process sandbox, terminal, or language server;\n- automatic Drive9 mounting;\n- strong subprocess read-your-writes through WebDAV;\n- local-overlay support for either consistency profile;\n- LayerFS checkpoints or workspace rollback;\n- source-streaming or crash-recoverable tool capture;\n- exactly-once external tool side effects;\n- evidence enumeration.\n\nThe stock Harness spill policy receives a fully materialized tool result. Storage is\ndurable-before-reference, but tool output is not streamed to Drive9 at source in V1.\n\n## Development\n\n```bash\nnpm ci\nnpm run check\nnpm test\nnpm run test:race\nnpm run build\nnpm pack --dry-run\n```\n\nThe default suite includes a scripted **real Harness agent loop**: the model uses the\nstock filesystem tool, `/bin/cat` reads the same mounted bytes, an oversized result is\nspilled, and later model steps invoke `result_search` and `result_read`.\n\nFor a real Drive9 service and Linux FUSE mount created with\n`drive9 mount --mode=fuse --profile=none`:\n\n```bash\nDRIVE9_REAL_E2E=1 npm run test:real\n```\n\nRequired environment and cleanup behavior are documented in\n[docs/operations.md](docs/operations.md). See [CONTRIBUTING.md](CONTRIBUTING.md) for\nthe release checklist. The real test rejects non-Linux and non-FUSE mount roots.\n\n## Compatibility\n\n| Component or profile | Supported contract |\n| --- | --- |\n| Node.js | 22.19 or newer |\n| DeepSeek Harness | `0.1.0-rc.6` |\n| Drive9 JavaScript SDK | `0.1.4` |\n| `strong` | Linux Drive9 FUSE; writes wait for exact process-visible bytes. Current real-service validation observed SDK-to-mount convergence in 1.3–1.5 seconds and mount-close-to-new-SDK-revision convergence in 0.36–0.40 seconds. These observations are not an SLA. |\n| `eventual` | WebDAV; no subprocess read-your-writes guarantee, with observed staleness beyond 30 seconds. |\n\nDeepSeek Harness is a developer preview. Upstream service-contract changes require a\nnew package release and contract review.\n","readmeFilename":"README.md","_rev":"1-7af23c9b6c56d428289bcb607d46477c"}