Atlas / Skills / lc044 / TrailSnap

TrailSnapBLOCK

skills/lc044/trailsnap

TrailSnap (行影集) | AI-Powered open-source photo album for travel & life memories.(AI赋能的开源相册工具,珍藏旅行与生活点滴)

Verdict
BLOCK
Grade
F
Trust score
48 /100
Version
—
Hosts
4 documented
License
AGPL-3.0
Stars
785
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

English | 中文

TrailSnap 是一个智能化的 AI 相册应用,致力于帮助用户轻松记录、整理和回顾自己的出行经历。通过强大的 AI 处理能力,让每一张照片和每一段旅程都成为值得珍藏的记忆。 未来每个人(至少每个家庭)都有一个属于自己的 AI 数据中心,而相册是数据中心的一个重要数据来源,它留存了你生活中的很多瞬间,TrailSnap 致力于将这些瞬间转化为有价值的记忆,它可以帮你默默地记录下相册里的车票、景点门票,可以帮你记录旅行中的所见所闻,可以帮你自动整理出可以发朋友圈的照片(甚至帮你准备好文案),可以帮你剪一段15s的短视频······。 把旅行从"拍过"变成"可留念、可展示、可分享"。TrailSnap 做的,是让每一段出行都值得珍藏。 所以,我给这个项目命名为 《行影集》,在这里你的数据才 "真正属于你"。
Read from source at commit cedd0e3d1467OBSERVED · 2026-10-12
02

Install

Commands as the repository documents them. They are shown, not run.

git clone https://github.com/<your-username>/TrailSnap.git
uv sync
uv sync --extra cpu   # CPU 版本
uv sync --extra gpu   # GPU 版本 (CUDA 12.8)
uv sync
uv sync --extra cpu
03

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
claude-codementioned
codexmentioned
cursormentioned
openclawmentioned
04

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: trailsnap-agent
description: Query a user's TrailSnap photo library through scoped MCP tools to find photos, reconstruct memories, build person timelines, create evidence-backed narratives, or propose an album plan for explicit in-app approval. Use for the user's own TrailSnap library; never claim a proposal was executed or changed the library.
---

# TrailSnap Agent

Use the `trailsnap_*` tools supplied by the TrailSnap Pi extension. Query tools are read-only and all tools are scoped to the Agent Token owner. `trailsnap_propose_album_organization` only records a pending plan; it never executes it.

- Start with the narrowest tool that answers the request. Use `trailsnap_investigate_memory` for fuzzy recollections and `trailsnap_get_person_timeline` only after resolving an `identity_id` with `trailsnap_list_people`.
- Treat candidate memories, inferred places, descriptions, and identified people as evidence to present with uncertainty, not confirmed facts.
- Paginate when the first result says more data is available. Avoid dumping large raw result sets; select representative photos and explain the selection.
- Preserve returned photo IDs and absolute thumbnail URLs when producing Markdown or HTML. Never invent a media URL or expose a local file path.
- Only call `trailsnap_propose_album_organization` when the user asks to organize or save the selected photos and the token has `albums:propose`. Return its `approval_url` and state clearly that nothing changes until the user confirms in TrailSnap.
- Never attempt to execute or approve a plan. Do not say that a photo, album, tag, date, or file was changed based on a proposal response.

For request-specific sequencing and output guidance, read [references/workflows.md](references/workflows.md).
05

Trust audit

BLOCKgrade F · trust 48/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (7 observation(s))
Network
declared (8 observation(s))
Shell
declared (3 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
package/server/scripts/benchmark_face_matching.py:62
exec(compile(ast.Module(body=methods, type_ignores=[]), "<baseline-face-matching>", "exec"), namespace)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
package/server/scripts/benchmark_thumbnail_quality.py:32
exec(compile(source, 'baseline_storage.py', 'exec'), baseline.__dict__)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.binary · CWE-1104
package/desktop/src-tauri/icons/icon.icns
icon.icns
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInsecure crypto · crypto.weak_random · CWE-327, CWE-338
package/server/app/api/system.py:264
map_key = random.choice(keys)
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
package/trailsnap-cli/trailsnap/commands/config.py:50
print(f"API Token: {token[:10]}...{token[-5:]}" if len(token) > 15 else f"API Token: {token}")
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
package/official-site/public/install.ps1:1
<#
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
scripts/dev-services-down.ps1:1
<#
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
scripts/dev-services-up.ps1:1
<#
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/tests.yml:220
DB_URL: postgresql://trailsnap:trailsnap@localhost:55432/trailsnap
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/tests.yml:221
TS_DB_URL: postgresql://trailsnap:trailsnap@localhost:55432/trailsnap
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/tests.yml:224
RAILWAY_DB_URL: postgresql://trailsnap:trailsnap@localhost:55432/trailsnap
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
README.md:171
- DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
README.md:172
- RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
package/website/tests/e2e/specs/views-coverage/views-deeper-p8.spec.ts:81
token: "tsnap_active_abcdefghijklmnop",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
package/website/tests/e2e/specs/views-coverage/views-deeper-p8.spec.ts:162
token: "tsnap_new_abcdefghijklmnop",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
package/website/tests/e2e/specs/views-coverage/views-deeper-p8.spec.ts:222
token: "tsnap_del_abcdefghijklmnop",
LOWInventory / provenance · inv.binary · CWE-1104
package/website/android/app/trailsnap-debug.keystore
trailsnap-debug.keystore
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.binary · CWE-1104
package/website/android/gradle/wrapper/gradle-wrapper.jar
gradle-wrapper.jar
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.hidden_file · CWE-1104
tests/.env.test.ci
.env.test.ci
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
tests/.env.test.example
.env.test.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
package/website/tests/unit/diary-pagination.test.cjs:9
new Function('exports', 'module', code)(moduleExports.exports, moduleExports)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
package/website/tests/unit/moment-layout.test.cjs:12
new Function('require', 'module', 'exports', code)(name => dependencies[name] ?? require(name), module, module.exports)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
package/server/app/api/media.py:87
digest = hashlib.md5()
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
package/server/app/api/media.py:627
md5 = hashlib.md5() if expected_md5 else None
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
package/server/app/api/media.py:688
md5_digest = hashlib.md5() if expected_md5 else None

Gates applied: no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha cedd0e3d1467full audit observations/trust-audit/skill/lc044__trailsnap.json · Report an issue / request a re-scan
06

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-12cedd0e3d1467BLOCKF48first audit
07

Questions

What does the TrailSnap skill do?

TrailSnap (行影集) | AI-Powered open-source photo album for travel & life memories.(AI赋能的开源相册工具,珍藏旅行与生活点滴)

Is TrailSnap safe to install?

No — not without reading the findings first. The audit graded it F (48/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What can TrailSnap access on my machine?

The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: found — see the findings.

Which assistants does TrailSnap work with?

Its documentation mentions claude-code, codex, cursor and openclaw. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (cedd0e3d1467), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement