The wasm32-wasi optional native bindings (tailwindcss oxide, rolldown)
declare @emnapi/* ranges that now resolve to 1.11.3 / 1.2.3 on the
registry, but the committed lock still pinned the older .1/.2 patch
versions. npm ci (strict sync) therefore failed with EUSAGE, breaking
the deploy-admin fleet workflow. Regenerated the lock with
npm install --package-lock-only.
- parse skill package zips client-side, mirroring backend ingestion limits (ADR-0018)
- add zip upload flow on skills page and zip replace in SkillEditor
- group role skill bindings by the shared management folder tree (ADR-0028)
- add fflate dependency
Sessions resume across runs (ADR-0017). Without auto-compact the SDK jsonl
grows unboundedly — a 7-day / 26-run session hit 31 MB / 1995 lines, making
every API call resend the full history and inflating a trivial "change a
title" task to 22 minutes. Enable autoCompactEnabled in the SDK settings so
the SDK compacts automatically when the context window fills.
If StreamingAgentCard.finish cannot patch the live card, plain-text fallback
can still succeed with partial answer text. Interrupt is terminal — always
emit the explicit 已中断 notice when the card path failed so teachers see the
abort. Harden the integration assertion with waitFor.
Explorer POST /projects was dropping projectId/folderId/workspaceDir after a
narrowed response shape, breaking admin-explorer. Make seedTestOrganization
idempotent under shared-DB isolation, force single-worker vitest, and align the
OAuth no-membership redirect expectation with authRoutes.
Fail fast if TRUNCATE left Organization rows, drop the extra deleteMany
before seed create, and force vitest maxWorkers=1 so forks cannot race
the shared Postgres.
seedTestOrganization now wipes+creates instead of fragile upsert.
hub-check drops pull_request triggers so push/PR pairs no longer double
migrate against the runner; branch push status remains the gate.
deleteMany could not reliably clear nested agent-config folders and left
ghost Organization rows that broke the next upsert. Truncate every public
table except _prisma_migrations before seeding the default org.
parentId RESTRICT prevented Organization.deleteMany from clearing nested
folder trees during test resetDb, leaving half-wiped rows and breaking
subsequent upserts. Service still refuses non-empty folder deletes;
DB cascade only unblocks org teardown / full wipe.
Admin routes always construct OrganizationAgentConfiguration via
readSkillStoreRoot(); CI and local runs without HUB_SKILL_STORE_ROOT
failed open. Seed a tmp root when unset. Also make preflight CLI tests
honor DATABASE_URL and set the skill-store env in hub-check.
CI hub-check reaches Postgres as the service hostname `postgres`, but
helpers hard-coded 127.0.0.1:5432, so migrate ran against the service
while vitest connected to the wrong place. Prefer env when set.
Act/docker runners commonly block non-privileged user namespaces, so
setpriv+CapEff=0 cannot run bwrap. Gate the proof on `unshare --user`
and keep unit + remaining integration tests as the default CI net.
Claude SDK may report an extra host/doctor skill id even with
disableBundledSkills. Keep the ADR-0018 guarantee: managed outline
loads and workspace-local untrusted skills do not.
agent-sandbox-linux requires uid>0, CapEff=0, and NoNewPrivs=1. Act runners
often execute as root with residual caps; create cphci and drop privileges
via setpriv before vitest.
hub build runs admin:build; fleet deploy already npm ci --prefix admin-web
but hub-check only installed hub/. Without that, vite fails on @sveltejs/kit.
Concurrent hub-check jobs on the shared runner fought over published
host ports (5432 then 15432). Drop host port mapping and connect to the
service container as postgres:5432 on the job network.
Runner host 5432 is already allocated (leftover containers), causing
hub-check service Postgres to fail start. Map service DB to 15432 and
point wait/integration DATABASE_URL at that port.
Rebased feat/agent-config-folder-tree onto current main, keeping cursor
invalidation (not session archive) and requireFolder helpers. Regenerated
package-lock so npm ci finds @emnapi/*; tighten session-cursor test assert
for missing claudeSessionId key.
Add a shared transparent OrganizationAgentConfigFolder tree for grouping
agent roles and skills in the admin UI without affecting identity, bindings,
run loading, or slash commands.
Agent tool downloads and trigger attachment staging both used the SDK
messageResource path, which fails closed for multi-MB teacher files and
did not share the bot-identity transport contract. Route every download
through Hub-owned createFeishuBotCli (secret via stdin, disposable HOME,
HUB_FEISHU_CLI_BIN), keep workspace containment on write, and inject the
adapter in trigger tests.
SubmitDocParserJobAdvance uploads PDFs to Aliyun OSS via tea/httpx, which
defaults readTimeout to 3000ms when RuntimeOptions is empty. Multi-MB
teacher PDFs on para silo failed with ReadTimeout(3000) before the job
could start. Set connectTimeout=15s and readTimeout=5m.
createReadStream emits async ENOENT without a listener, which became an
unhandled 'error' event and exited the silo process. Teachers then saw the
startup "process restart" notice. Wait for stream open and convert missing
files into DocmindClientError instead.
The claude_code preset exposed Agent/SendMessage/Task. Background agents
abort with reason "background", which the SDK maps to Bash
toolDenialKind "cancelled" ("user doesn't want this action") and freezes
command execution mid-run.