diff --git a/.project-docs/00-brief/success-criteria.md b/.project-docs/00-brief/success-criteria.md index b800fa5..eb4160a 100644 --- a/.project-docs/00-brief/success-criteria.md +++ b/.project-docs/00-brief/success-criteria.md @@ -2,9 +2,10 @@ ## Project Success -- 已登记业务能从手工输入或 AgentBus 输入稳定路由到统一 operation 契约。 +- 已登记业务能从获授权员工的手工输入或账号绑定的 AgentBus 输入稳定路由到统一 operation 契约;管理员只进入管理面,所有任务接口和数据库 task principal 都失败关闭。 - 写能力只在唯一对象、页面身份、ownership、写前投影、明确服务端响应和 action-specific 完成凭据成立时执行。 -- ERP 执行以不可变任务归属账号为队列边界:同账号保持 FIFO 与单活跃执行,不同账号互不阻塞;管理员查看权限不能进入他人任务的事件、领取或插件回执链路。 +- ERP 执行以不可变任务归属账号为队列边界:同账号保持 FIFO 与单活跃执行,不同账号互不阻塞;登录 ERP 身份只能由唯一账号节点的规范化精确相等证明,且管理员没有任务读取、事件、领取、回执或删除权限。 +- 组长看板只读覆盖固定组织内所有已明确归属的手工与 AgentBus 任务,以不可变 assignee 作为员工口径;无可靠归属的历史记录不猜测归属,查看权限不扩展任务或 ERP 权限。 - 有效组长身份绑定可用 AgentBus 渠道后,系统自动从当前账号的 AgentBus 路由开始发送未来稳定结果;通知使用独立加密队列,失败不改变任务状态,摘要不扩大任务或 ERP 权限,也不暴露原始指令、客户资料或技术载荷。 - 归档/恢复与永久强制删除保持为两个明确操作;强制删除不受任务状态门禁限制、完整移除任务平台记录,并明确不代表回滚既有 ERP 写入。 - 当前发布物、源码和机器可读发布清单逐文件、逐哈希一致。 diff --git a/.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md b/.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md index 006bedc..5f8c9cf 100644 --- a/.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md +++ b/.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md @@ -2,7 +2,7 @@ ## Status -Accepted; superseded in part by AUTH-002 +Accepted; superseded in part by AUTH-002 and AUTH-004 ## Date @@ -10,7 +10,7 @@ Accepted; superseded in part by AUTH-002 ## Supersession Note -AUTH-002 supersedes only this ADR's organization-wide ERP FIFO and archive-only removal clauses. The remaining fixed-scope account, role, route-grant, owner-isolation, dashboard, AgentBus assignment, browser-worker, and ERP-identity decisions remain active. Current execution-queue and deletion behavior must be read from AUTH-002. +AUTH-002 supersedes this ADR's organization-wide ERP FIFO and archive-only removal clauses. AUTH-004 additionally supersedes administrator task creation, all-route possession, task-wide reads, dashboard access, task transitions, and force-delete authority, plus the manual-task-only leadership-dashboard scope. The remaining fixed-scope account, employee route-grant, owner-isolation, AgentBus assignment, browser-worker, and ERP-identity decisions remain active. Current execution-queue and employee deletion behavior must be read from AUTH-002; current administrator and dashboard boundaries must be read from AUTH-004. ## Context @@ -20,16 +20,16 @@ The platform already required login but treated the fixed deployment scope as a - Keep one internal `organization_id` deployment scope and do not expose organization selection or tenant administration. - Use three roles: `admin`, `team_lead`, and `user`. -- Administrators manage account lifecycle, passwords, sessions, global settings/audit, AgentBus channels, and all manual/AgentBus task visibility. They always hold all 18 registered manual business routes, but their inspection authority does not grant ERP execution authority over work assigned to another account. +- Superseded by AUTH-004 for task access: administrators manage account lifecycle, passwords, sessions, global settings/audit, AgentBus channels, parser routing, and employee grants, but hold no business routes and do not enter the task data plane. - Password entry points require a non-empty value but impose no application-level minimum or maximum length. The platform does not force a password change on first login or after an administrator reset; voluntary self-service change, administrator reset, and session revocation remain supported. The historical `must_change_password` column is compatibility-only and is cleared on password writes. -- Team leads and ordinary users use normal business APIs only for their own manual tasks. New non-administrator accounts start with no task-type grants and may invoke only routes explicitly granted by an administrator. +- Team leads and ordinary users use normal business APIs only for tasks assigned to themselves, whether created manually or through AgentBus. New non-administrator accounts start with no task-type grants and may invoke only routes explicitly granted by an administrator. - Re-read route authorization before intake and relevant task state transitions. Known denied routes and unknown/non-unique routes fail closed before parsing, plugin dispatch, or ERP execution. -- Give team leads a dedicated read-only platform-operations dashboard over all manual account tasks. It is an aggregate-first leadership view across task, person, original input, final output, time, task type, and completion state; every aggregate may drill into the same bounded business-facing task projection. +- Superseded in scope by AUTH-004: give team leads a dedicated read-only platform-operations dashboard over every durably assigned manual and AgentBus task, using immutable assignment as the employee dimension. Administrators do not access this dashboard. - Keep the leadership dashboard separate from audit and engineering diagnostics. It never renders parser/executor payloads, internal identifiers, codes, machine-shaped historical input, or technical failure text; those values are replaced by a concise business explanation without changing the underlying audit evidence. - Keep leadership summary cards display-only. Status changes are explicit filter-form actions, default to all results, and retain the business-facing merge of internal attention states into “进行中”. - Superseded by AUTH-002 for removal behavior: preserve creator and input-turn attribution with encrypted input at rest. The original decision exposed archive/restore only and did not expose irreversible purge. - Bind each enabled AgentBus channel to exactly one active `user` or `team_lead` account with a configured, case-insensitively unique expected ERP account. Administrator accounts remain unbound from employee channels. -- Execute inbound AgentBus work under the bound employee identity and that account's route allowlist. Persist one immutable task assignee for both manual and AgentBus work; confirmation, browser claim/result, reconciliation, and resume require the assignee even when the caller is an administrator. +- Execute inbound AgentBus work under the bound employee identity and that account's route allowlist. Persist one immutable task assignee for both manual and AgentBus work; confirmation, browser claim/result, reconciliation, and resume require that employee assignee. Administrators cannot invoke those transitions. - Allow only one fresh browser execution worker per account. Heartbeats must match the account's expected ERP identity; a second fresh worker or mismatched ERP session fails closed, and automatic failover begins only after the prior worker is stale. - Superseded by AUTH-002 for queue scope: the original decision preserved organization-wide ERP FIFO serialization. Employee worker binding chose who could execute but did not authorize parallel ERP writes. @@ -40,9 +40,9 @@ This model fits a single-organization deployment while enforcing least privilege ## Consequences - Migrations 015–018 must be applied before the updated control plane starts. -- Existing accounts migrate as administrators; newly created team leads and users require explicit task grants. +- Existing accounts originally migrated as administrators; under AUTH-004, administrator identities are management-only and newly created team leads/users require explicit task grants. - Existing historical `must_change_password=true` values do not restrict login, reads, or mutations; no destructive migration is required to retire the forced-change flow. -- Permission revocation can block an existing task at confirmation or browser claim even when an administrator attempts the transition. +- Permission revocation can block an existing task at confirmation or browser claim; administrators cannot attempt either transition. - Existing unbound AgentBus channels and historical unassigned AgentBus tasks remain non-executable until an administrator completes an explicit employee binding; no assignee is inferred from whichever browser is online. - Extension `0.5.164` is the first release carrying the expected-ERP identity probe required by this worker contract. - Cross-user operational visibility is intentionally separated from normal task mutation and technical debugging surfaces. @@ -52,6 +52,10 @@ This model fits a single-organization deployment while enforcing least privilege - The implicit administrator-only, organization-shared account behavior of the earlier control-plane baseline. +## Revision + +- 2026-09-07: AUTH-004 removed administrators from the task data plane and expanded the team-lead dashboard from manual-origin work to all durably assigned manual and AgentBus tasks. + ## Related - `control-plane/migrations/015_account_roles_and_task_audit.sql` @@ -61,3 +65,4 @@ This model fits a single-organization deployment while enforcing least privilege - `.project-docs/30-worklog/tasks/20260901-account-system-impl-d4e7a2.md` - `.project-docs/30-worklog/tasks/20260901-leadership-dashboard-c4b9e1.md` - `.project-docs/30-worklog/tasks/20260902-integrate-all-push-c93a7f21.md` +- `.project-docs/10-decisions/AUTH-004-admin-management-plane-and-leader-oversight.md` diff --git a/.project-docs/10-decisions/AUTH-002-account-scoped-execution-and-force-delete.md b/.project-docs/10-decisions/AUTH-002-account-scoped-execution-and-force-delete.md index 48025d4..218702c 100644 --- a/.project-docs/10-decisions/AUTH-002-account-scoped-execution-and-force-delete.md +++ b/.project-docs/10-decisions/AUTH-002-account-scoped-execution-and-force-delete.md @@ -2,12 +2,16 @@ ## Status -Accepted +Accepted; superseded in part by AUTH-004 ## Date 2026-09-03 +## Supersession Note + +AUTH-004 supersedes this ADR's administrator-wide task read model and administrator force-delete authority. Per-assignee FIFO, assignee-only executable routing, reversible archive/restore, and lifecycle-independent force delete remain active for the owning `team_lead` or `user` account. + ## Context AUTH-001 bound each task to one employee account and one matching ERP browser worker, but retained organization-wide ERP FIFO and archive-only operator removal. In production, one blocked or stale account could therefore hold every other employee's work behind the same queue. Administrator-wide task visibility also shared paths with executable event delivery, allowing an administrator page and plugin to observe or attempt to process another employee's task. Finally, an active or waiting task could fail the archive gate and then could not be permanently removed, leaving the same blocked state in place. @@ -19,9 +23,9 @@ The user explicitly required independent execution across accounts, FIFO only wi - Use immutable `tasks.assigned_user_id` as the ERP execution queue and routing partition. - Serialize browser claims with an advisory transaction lock scoped to organization plus assigned account. Active-execution checks, confirmed FIFO selection, and queue positions include only that account's tasks. - Preserve deterministic FIFO and at most one active ERP execution for one assigned account. A different assigned account's active, queued, stale, or uncertain task does not block this account and does not occupy its queue position. -- Keep administrator-wide task visibility as a read model only. Executable SSE history/live events, browser claims, plugin-result ingestion, and browser cleanup commands are accepted or delivered only for the authenticated account matching the task's immutable assignee, including when the signed-in role is administrator. +- Superseded by AUTH-004 for administrators: task reads and executable SSE, browser claims, plugin results, and cleanup commands are available only to a `team_lead` or `user` session matching the immutable assignee. Administrators have no task read model. - Keep archive and restore as the reversible routine workflow, with their existing lifecycle-state guard. -- Expose separately confirmed force delete through the single-task and bulk-delete APIs. Force delete intentionally has no parse, handoff, queue, or ERP-execution status gate, while retaining organization and owner authorization. +- Expose separately confirmed force delete through the single-task and bulk-delete APIs. Force delete intentionally has no parse, handoff, queue, or ERP-execution status gate, while requiring the owning employee account under AUTH-004. - On force delete, remove the task, task-owned records through existing cascades, and task outbox entries atomically. Retain only a minimal non-content `task.hard_deleted` audit marker, then request OSS artifact cleanup and owner-plugin local cancellation/cache cleanup after commit on a best-effort basis. - Force delete removes platform state only. It cannot roll back an ERP write that already happened, and the operator warning must state this explicitly. @@ -33,10 +37,10 @@ The execution account is already the durable link between the platform user, Age - Two employees with distinct assigned accounts and valid matching workers may execute concurrently; tasks for either employee remain FIFO and single-active within that employee's queue. - An uncertain ERP result blocks only the same assigned account's later claims unless an authorized operator explicitly force-deletes the platform task or resolves it through the existing reconciliation workflow. -- Administrators may inspect and force-delete authorized organization tasks, but their browser never receives or submits another employee's executable task events, plugin results, or cleanup command. +- Superseded by AUTH-004: administrators may neither inspect nor force-delete business tasks. The owning employee session alone receives executable task events, plugin results, and cleanup commands. - A force-deleted task and its task-owned evidence cannot be restored. The retained audit marker proves the destructive action without retaining task content. - No database migration or Chrome extension source/version change is required. The control-plane and platform UI must be deployed together before relying on the behavior. -- Runtime acceptance requires an authorized administrator-plus-two-employees staging matrix, including cross-account concurrency, same-account FIFO, administrator event isolation, and waiting/active force deletion. +- Runtime acceptance requires separate management and employee sessions plus two employee workers, including cross-account concurrency, same-account FIFO, administrator task-API denial, and owner-performed waiting/active force deletion. ## Supersedes @@ -45,6 +49,8 @@ The execution account is already the durable link between the platform user, Age All other AUTH-001 account, role, route-grant, ownership, dashboard, session, AgentBus, and expected-ERP-identity decisions remain active. +AUTH-004 is the current authority for administrator task isolation and leadership-dashboard scope. + ## Related - `.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md` @@ -53,3 +59,4 @@ All other AUTH-001 account, role, route-grant, ownership, dashboard, session, Ag - `control-plane/src/task-service.ts` - `control-plane/src/server.ts` - `LianSyn-platform/app.js` +- `.project-docs/10-decisions/AUTH-004-admin-management-plane-and-leader-oversight.md` diff --git a/.project-docs/10-decisions/AUTH-004-admin-management-plane-and-leader-oversight.md b/.project-docs/10-decisions/AUTH-004-admin-management-plane-and-leader-oversight.md new file mode 100644 index 0000000..1e7284f --- /dev/null +++ b/.project-docs/10-decisions/AUTH-004-admin-management-plane-and-leader-oversight.md @@ -0,0 +1,56 @@ +# AUTH-004: Management-only administrators and assignee-based leader oversight + +## Status + +Accepted + +## Date + +2026-09-07 + +## Context + +The fixed-scope account model previously let administrators create and inspect business tasks while withholding only employee ERP execution. This still placed administrator sessions, pages, and database principals inside the task data plane. Separately, the team-lead operations dashboard was restricted to manual tasks and used origin attribution, so assigned AgentBus work was absent from the leadership view. + +The user explicitly required administrators to be management-plane-only identities and required the group-leader dashboard to show every employee-assigned business task, regardless of manual or AgentBus intake. + +## Decision + +- Administrators manage accounts, roles, passwords, sessions, employee task-route grants, AgentBus channels, parser routing, automation settings, and audit. They cannot create, list, inspect, mutate, confirm, claim, reconcile, archive, restore, force-delete, stream, or submit results for business tasks. +- Administrator sessions do not register browser workers, open task SSE, call the ERP extension bridge, receive task cleanup commands, own employee channels, hold business-route grants, or become leader-summary subscribers or recipients. +- Only active `team_lead` and `user` identities enter the task data plane. Their normal task APIs, executable events, browser claims/results, reconciliation, archive/restore, and force delete remain restricted to immutable `assigned_user_id`. +- The operations dashboard is available only to team leads. It is an organization-wide, read-only business projection over durably assigned `manual` and `agentbus` tasks. Employee rankings, person filters, search, pagination, and detail use immutable `assigned_user_id`; historical AgentBus rows without an assignee are excluded rather than inferred. +- Dashboard visibility does not grant cross-user task mutation, executable events, artifacts, browser access, reconciliation, or ERP authority. AUTH-002 account-scoped queues and AUTH-003's separate privacy-bounded leader-summary outbox remain unchanged. +- Migration `021_admin_task_data_plane_isolation` removes legacy administrator task assignments and executable bindings without deleting task history, then uses database constraints and role-promotion cleanup to prevent administrators from re-entering task-principal relationships. + +## Rationale + +Separating management identities from business-task identities eliminates accidental administrator assignment, execution, and data exposure at the server and database boundaries. Using immutable assignment for the team-lead read model makes manual and AgentBus work consistent without inventing ownership for historical rows or weakening employee execution isolation. + +## Consequences + +- Migrations through `021_admin_task_data_plane_isolation` must complete before the updated application starts. +- Existing administrator-assigned tasks keep their historical task rows but lose executable assignment and leases. Administrator channels, browser workers, route grants, active summary subscriptions, and pending summary deliveries are disabled or removed. +- Administrators are redirected to management pages and cannot use the task history or operations dashboard. Operational canaries require separate administrator and employee/team-lead sessions. +- Team leads can inspect all assigned manual and AgentBus work through the bounded business-facing dashboard while normal task operations remain owner-only. +- Production migration, deployment, restart, and role/device canaries remain separately authorized runtime work. + +## Supersedes + +- AUTH-001 clauses granting administrators all manual routes, manual task creation, organization-wide task visibility, dashboard access, or assignee task transitions. +- AUTH-001's manual-task-only dashboard scope and origin-based employee attribution. +- AUTH-002 clauses retaining administrator-wide task reads or administrator force-delete authority. + +AUTH-002's per-assignee execution queues and employee force-delete semantics remain active. AUTH-003 remains active without change. + +## Related + +- `.project-docs/10-decisions/AUTH-001-fixed-scope-account-authorization.md` +- `.project-docs/10-decisions/AUTH-002-account-scoped-execution-and-force-delete.md` +- `.project-docs/10-decisions/AUTH-003-leader-task-summary-notifications.md` +- Feature commit `9043ad6eda0deb2a620e1303467d1c3bd80374ed` +- Feature commit `a2378c8` +- `control-plane/migrations/021_admin_task_data_plane_isolation.sql` +- `control-plane/src/task-service.ts` +- `control-plane/src/server.ts` +- `LianSyn-platform/app.js` diff --git a/.project-docs/10-decisions/EXT-001-central-service-host-extension-updates.md b/.project-docs/10-decisions/EXT-001-central-service-host-extension-updates.md index 6cb1bd4..9942622 100644 --- a/.project-docs/10-decisions/EXT-001-central-service-host-extension-updates.md +++ b/.project-docs/10-decisions/EXT-001-central-service-host-extension-updates.md @@ -10,9 +10,9 @@ Reverted ## Reversal -On 2026-09-03 the user explicitly directed that this iteration be backed up and its server-side automatic-update architecture removed from the main branch, then clarified that the Chrome plugin itself must remain at `0.5.167`. The exact full-stack state at commit `b2e33e2e5d29138891eabc93969cf24907492dfe` is preserved on remote branch `codex/backup-extension-update-20260903-b2e33e2`; active `main` keeps the exact `0.5.167` plugin source/package but restores the control plane to migration 018 with no private-OSS/ECS update orchestration. +On 2026-09-03 the user explicitly directed that this iteration be backed up and its server-side automatic-update architecture removed from the main branch, then clarified that the Chrome plugin itself must remain at `0.5.167` at that rollback point. The exact full-stack state at commit `b2e33e2e5d29138891eabc93969cf24907492dfe` is preserved on remote branch `codex/backup-extension-update-20260903-b2e33e2`. Active `main` later advanced the manually distributed plugin to `0.5.169` and the control plane to migration 021 without restoring private-OSS/ECS update orchestration. -This ADR is retained only as historical server-architecture context and no longer governs the active control plane. Plugin-side idle proof and guarded reload handlers remain as dormant `0.5.167` capabilities with no current server/platform trigger. The reverted server code was never deployed, migration 019 was not applied, no OSS extension release was published, and no Cloud Assistant or Chrome reload action was performed by these repository tasks. +This ADR is retained only as historical server-architecture context and no longer governs the active control plane. Plugin-side idle proof and guarded reload handlers remain as dormant capabilities in `0.5.169` with no current server/platform trigger. The reverted server code was never deployed, migration 019 was not applied, no OSS extension release was published, and no Cloud Assistant or Chrome reload action was performed by these repository tasks. ## Context diff --git a/.project-docs/10-decisions/decision-index.md b/.project-docs/10-decisions/decision-index.md index 2c73c45..236b50e 100644 --- a/.project-docs/10-decisions/decision-index.md +++ b/.project-docs/10-decisions/decision-index.md @@ -10,9 +10,10 @@ | RELEASE-001 | Current artifacts, filenames, versions, and SHA-256 values are defined only by `dist/release-manifest.json`. | Active | 2026-08-28 | Release and delivery | [Release manifest](../../dist/release-manifest.json) | | SAFETY-001 | Real ERP access/write, task mutation, extension reload, service restart, deployment, and external delivery require explicit task-scoped authorization. | Active | 2026-08-28 | Operations and maintenance | [Governance](../../AGENTS.md) | | NETWORK-001 | In the trusted internal deployment, AgentBus roster attachment URLs may resolve to internal/private addresses; HTTPS, credential rejection, DNS pinning, redirect validation, bounds, and digest checks remain. | Active | 2026-08-31 | AgentBus attachment ingress | [Reply contract](../../agent设计规范/agentbus-reply-contract.md) | -| AUTH-001 | The fixed deployment scope uses administrator-managed `admin`, `team_lead`, and `user` accounts, owner-isolated normal tasks, display-only leadership metrics with explicit filtering, explicit non-admin route grants, and assignee-bound AgentBus/browser/ERP execution. | Active except clauses superseded by AUTH-002 | 2026-09-01 | Authentication, authorization, audit, AgentBus workers, and operations oversight | [ADR](AUTH-001-fixed-scope-account-authorization.md) | -| AUTH-002 | ERP execution is serialized per immutable assigned account, administrator visibility is never execution routing, and explicit force delete physically removes authorized tasks regardless of lifecycle state. | Active | 2026-09-03 | ERP claim queues, executable events/results, and task removal | [ADR](AUTH-002-account-scoped-execution-and-force-delete.md) | +| AUTH-001 | The fixed deployment scope uses administrator-managed `admin`, `team_lead`, and `user` accounts, explicit employee route grants, and assignee-bound AgentBus/browser/ERP execution. | Active except clauses superseded by AUTH-002 and AUTH-004 | 2026-09-01 | Authentication, authorization, audit, AgentBus workers, and operations oversight | [ADR](AUTH-001-fixed-scope-account-authorization.md) | +| AUTH-002 | ERP execution is serialized per immutable assigned account, and explicit owner force delete physically removes authorized tasks regardless of lifecycle state. | Active except administrator task-access clauses superseded by AUTH-004 | 2026-09-03 | ERP claim queues, executable events/results, and task removal | [ADR](AUTH-002-account-scoped-execution-and-force-delete.md) | | AUTH-003 | Active team-lead identities automatically receive an organization-wide read projection through their current-owner AgentBus route and a separate encrypted outbox; it never grants task or ERP authority. | Active | 2026-09-07 | Team-lead notifications, AgentBus outbound routing, and summary privacy | [ADR](AUTH-003-leader-task-summary-notifications.md) | +| AUTH-004 | Administrators are management-plane-only identities; team leads alone receive an assignee-based, cross-source operations dashboard while employee task operations remain owner-only. | Active | 2026-09-07 | Administrator isolation, task APIs, database principals, and leadership oversight | [ADR](AUTH-004-admin-management-plane-and-leader-oversight.md) | ## Superseded And Reverted Decisions @@ -20,7 +21,8 @@ |---|---|---|---| | DOC-LEGACY-001 | Root `task_plan.md`, `findings.md`, and `progress.md` were the active project-memory system. | DOC-001 | 2026-08-28 | | AUTH-001 (partial) | Organization-wide ERP FIFO and archive-only operator removal. | AUTH-002 | 2026-09-03 | -| EXT-001 | Central-service private-OSS and ECS Cloud Assistant orchestration for shared unpacked-extension updates. | Server architecture reverted by explicit user decision; exact full implementation is preserved on `codex/backup-extension-update-20260903-b2e33e2`, while plugin `0.5.167` remains current. | 2026-09-03 | +| AUTH-001 / AUTH-002 (partial) | Administrator task creation, task-wide reads, dashboard access, task transitions, and force-delete authority; manual-only leadership dashboard scope. | AUTH-004 | 2026-09-07 | +| EXT-001 | Central-service private-OSS and ECS Cloud Assistant orchestration for shared unpacked-extension updates. | Server architecture reverted by explicit user decision; exact full implementation remains on `codex/backup-extension-update-20260903-b2e33e2`, while the active manually distributed plugin has advanced to `0.5.169`. | 2026-09-03 | ## Decision Criteria diff --git a/.project-docs/20-architecture/data-flow.md b/.project-docs/20-architecture/data-flow.md index 507fac2..9aa2a77 100644 --- a/.project-docs/20-architecture/data-flow.md +++ b/.project-docs/20-architecture/data-flow.md @@ -4,9 +4,9 @@ | Flow | Source | Destination | Notes | |---|---|---|---| -| Business directive | Manual workbench or AgentBus | Route orchestrator | Manual input uses the signed-in account; AgentBus input uses the channel's bound employee account and its route allowlist. | +| Business directive | Employee manual workbench or AgentBus | Route orchestrator | Manual input uses a signed-in team lead/user; AgentBus input uses the channel's bound employee account and its route allowlist. Administrators cannot enter this flow. | | AgentBus execution ownership | Enabled channel | Employee account → immutable task assignee → executable feed | One account owns at most one channel; unbound channels and unassigned historical tasks stay non-executable. | -| Manual account authorization | Signed-in account plus resolved business route | Intake and task-transition gates | Administrators hold all routes; team leads/users require explicit grants and unresolved routes fail closed | +| Manual account authorization | Signed-in employee plus resolved business route | Intake and task-transition gates | Team leads/users require explicit grants; administrators manage grants but hold none, and denied or unresolved routes fail closed. | | Parsing | Route orchestrator | AI Skill or deterministic Program parser | AI/Shadow/Auto/Program mode is frozen per task | | Operation | Parser | Control-plane task and confirmation | Must validate against the same final contract | | ERP execution | Confirmed task | Chrome extension and logged-in ERP page | Requires unique object, page identity, ownership, and write preflight | @@ -15,25 +15,25 @@ | WeChat roster attachment | Strict transport envelope plus one structured `payload.attachments[]` entry | Existing `awaiting_attachment` task | Explicit conversation ID wins; otherwise strict `Conversation:` supplies the fallback. Placeholder text alone never creates a task. | | Internal attachment download | Credential-free HTTPS URL | Bounded in-memory workbook bytes | Internal/private DNS answers are allowed; the selected address is pinned, every redirect is revalidated, and URL/host/IP/bytes are omitted from logs. | | Operational diagnostics | Service, request, task, parser, AgentBus, attachment, database, and cleanup stages | Structured stdout/stderr and bounded Docker logs | Correlation identifiers, codes, outcomes, and durations only; no secrets or business payloads. | -| Platform operations oversight | Manual task creator, encrypted instruction history, and readable outcome | Team-lead/administrator leadership projection | Display-only summaries plus explicit filters drive an aggregate-first task/person/input/output/time/type/completion view; list reads are bounded to one read-only connection and hydrate full details only for the current page. | +| Platform operations oversight | Durably assigned manual/AgentBus task, encrypted instruction history, and readable outcome | Team-lead-only leadership projection | Immutable assignee is the employee dimension; unassigned historical AgentBus rows are excluded. Display-only summaries plus explicit filters drive an aggregate-first task/person/input/output/time/type/completion view, with bounded list reads and page-only detail hydration. | | Team-lead task summary | Future stable manual/AgentBus task outcome for another non-admin employee | Role/channel reconciler → current-owner encrypted route → separate durable outbox → leader-owned AgentBus channel → WeChat | Automatic for active team leads with a usable route; employee replies are sent first, summary frames use stable IDs and explicit routing with no `reply_to`, and delivery failure never changes task state. | -| Browser worker selection | Immutable task assignee | One fresh account-bound browser connection | The heartbeat must match the account's expected ERP identity; a second fresh worker or identity mismatch is non-executable, with failover only after staleness. | +| Browser worker selection | Immutable task assignee | One fresh account-bound browser connection | The heartbeat must prove the expected ERP identity from one unique login node by normalized exact equality; missing, duplicate, blank, substring-only, or mismatched identity is non-executable, with failover only after staleness. | | Account-scoped ERP queue | Confirmed task assignee | Assigned account's browser worker | Organization-plus-account advisory locking preserves FIFO and at most one active execution for that account; another account's active, queued, stale, or uncertain work is outside this queue. | -| Executable event and result routing | Immutable task assignee | Matching authenticated platform page and plugin | SSE history/live events, claims, plugin results, and browser cleanup commands never use administrator-wide visibility and fail closed when the authenticated account is not the assignee. | -| Task removal | Authorized operator | Archive/restore or permanent force delete | Archive/restore remains reversible and state-gated. Explicit force delete has no lifecycle-state gate, removes task-owned platform records atomically, retains a minimal deletion audit marker, and performs post-commit artifact/plugin cleanup best effort. | +| Executable event and result routing | Immutable task assignee | Matching authenticated employee page and plugin | Task APIs, SSE history/live events, claims, plugin results, and browser cleanup commands require a team-lead/user session matching the assignee; administrators are rejected before task handling. | +| Task removal | Owning employee | Archive/restore or permanent force delete | Archive/restore remains reversible and state-gated. Explicit owner force delete has no lifecycle-state gate, removes task-owned platform records atomically, retains a minimal deletion audit marker, and performs post-commit artifact/plugin cleanup best effort. Administrators cannot invoke either path. | | Confirmation export | ERP source file | Archived source plus mobile delivery artifact | Visitor XLS becomes real XLSX; other types prefer PDF | | Release | Editable source | `dist/release-manifest.json` and versioned artifacts | Manifest owns current hashes and filenames | ## State Ownership -- PostgreSQL owns durable control-plane account, role, expected ERP identity, task-route grant, AgentBus channel owner, immutable task assignee, account-scoped queue/lease state, browser worker, session, confirmation, audit, archive, outcome state, and revisioned team-lead notification subscriptions/deliveries. Notification destinations and payloads remain encrypted at rest. A force-deleted task no longer exists in task state; only its minimal non-content deletion audit marker remains, while an already delivered external message cannot be retracted. +- PostgreSQL owns durable control-plane account, management/task-plane role constraints, exact expected ERP identity, employee task-route grant, AgentBus channel owner, immutable task assignee, account-scoped queue/lease state, browser worker, session, confirmation, audit, archive, outcome state, and revisioned team-lead notification subscriptions/deliveries. Migration 021 removes and rejects administrator task principals. Notification destinations and payloads remain encrypted at rest. A force-deleted task no longer exists in task state; only its minimal non-content deletion audit marker remains, while an already delivered external message cannot be retracted. - Production attachment bytes use the configured OSS provider; normalized sensitive fields remain encrypted. - Chrome extension local state is bounded execution/reconciliation support, not canonical business history. - `.project-docs/30-worklog/tasks/` owns task-local project memory; canonical project state is an integrated projection. ## External Interfaces -- Operator workbench at the control-plane service. +- Employee task workbench and separate administrator management pages at the control-plane service. - AgentBus WebSocket channels and attachment delivery. - Logged-in ERP browser pages under the Chrome extension host permissions. - PostgreSQL, OSS, deployment gateway, and authenticated artifact download. diff --git a/.project-docs/20-architecture/system-overview.md b/.project-docs/20-architecture/system-overview.md index e4dcfb4..214bc3f 100644 --- a/.project-docs/20-architecture/system-overview.md +++ b/.project-docs/20-architecture/system-overview.md @@ -2,7 +2,7 @@ ## Current Architecture -Authenticated manual or account-bound AgentBus input is routed through task-scoped AI/Shadow/Auto/Program orchestration into one validated operation contract. The control plane owns account, channel owner, immutable task assignee, account-scoped execution queue, browser worker, session, task-type authorization, confirmation, audit, reversible archive, explicit force-delete behavior, and role-driven automatic team-lead task-summary projection. The Chrome extension verifies the expected ERP account, resolves the unique ERP object, enforces page and write gates, performs native actions, and returns action-specific evidence. +Authenticated employee manual or account-bound AgentBus input is routed through task-scoped AI/Shadow/Auto/Program orchestration into one validated operation contract. The control plane separates the administrator management plane from the employee task data plane and owns account, channel owner, immutable task assignee, account-scoped execution queue, browser worker, session, task-type authorization, confirmation, audit, reversible archive, explicit owner force-delete behavior, and role-driven automatic team-lead task-summary projection. The Chrome extension verifies the expected ERP account from one unique login identity node by normalized exact equality, resolves the unique ERP object, enforces page and write gates, performs native actions, and returns action-specific evidence. ## Main Components @@ -10,7 +10,7 @@ Authenticated manual or account-bound AgentBus input is routed through task-scop |---|---|---| | `agent设计规范/` | Agent Prompt, five parsing Skills, business templates, business registry, and stable fixtures | Editable source for business semantics; not runtime evidence | | `schemas/` and `mappings/` | Parse-state, execution-state, ERP form, field, and lifecycle contracts | Current contracts only | -| `control-plane/` | Task/session persistence, parser orchestration, confirmation, audit, AgentBus channel ownership, task assignment, browser workers, attachments, receipts, encrypted leader-summary projection/outbox, and structured diagnostics | TypeScript source; build output goes to `.build/` | +| `control-plane/` | Management/task-plane authorization, task/session persistence, parser orchestration, confirmation, audit, AgentBus channel ownership, task assignment, browser workers, attachments, receipts, encrypted leader-summary projection/outbox, and structured diagnostics | TypeScript source; build output goes to `.build/`; migration 021 enforces administrator isolation | | `LianSyn-platform/` | Operator workbench and external parser adapter | Source and UI, not local task output | | `chrome-extension/ltjt-order-assistant/` | Logged-in ERP resolution, preflight, native execution, response handling, requery, and dormant idle/reload safety handlers | Current server/platform does not trigger automatic updates; any code change requires synchronized versioned release updates | | `dist/` | Versioned current deliverables and machine-readable release manifest | Not a compilation directory | @@ -21,19 +21,19 @@ Authenticated manual or account-bound AgentBus input is routed through task-scop - AI/Program parsing and ERP resolution/execution share the final operation contract but do not share authority. - Platform envelope fields such as task ID, account identity, authorization revision, session, parser decision, confirmation, transport, and audit never enter the business operation. -- The product is one fixed internal organization scope with three roles. Administrators manage accounts, channels, and all 18 manual routes; team leads and users are owner-scoped for normal tasks and require explicit per-route grants. Team leads additionally receive a dedicated read-only, manual-task-only platform-operations dashboard. Administrator-wide visibility does not permit executing another account's assigned ERP work. +- The product is one fixed internal organization scope with three roles. Administrators are management-plane-only identities: they manage accounts, channels, employee route grants, parser routing, automation settings, and audit but cannot create, inspect, mutate, stream, claim, reconcile, delete, or execute business tasks. Team leads and users require explicit per-route grants and are owner-scoped for normal task operations. Team leads alone receive a dedicated organization-wide, read-only platform-operations dashboard over durably assigned manual and AgentBus tasks. - Account passwords are accepted when non-empty without an application-level length rule. First-login forced password changes are disabled; voluntary changes and administrator resets still revoke the relevant sessions, while the historical `must_change_password` column remains compatibility-only storage. -- The leadership dashboard is an aggregate-first projection across task, person, original input, final output, time, task type, and completion state. Summary cards are display-only; filtering is explicit and defaults to all results. List reads use one bounded read-only database transaction, SQL prefiltering, selective historical-message hydration, and full detail projection only for the current 20-row page. Its drill-through stays business-facing; technical payloads, internal identifiers, machine-shaped historical input, and technical failure text remain in separate authorized audit/engineering surfaces. +- The leadership dashboard is an aggregate-first projection across assigned task, employee, original input, final output, time, task type, and completion state. It includes only durably assigned `manual` and `agentbus` work and uses immutable `assigned_user_id` for rankings, people filters, search, pagination, and detail; historical unassigned AgentBus rows are excluded. Summary cards are display-only; filtering is explicit and defaults to all results. List reads use one bounded read-only database transaction, SQL prefiltering, selective historical-message hydration, and full detail projection only for the current 20-row page. Its drill-through stays business-facing; technical payloads, internal identifiers, machine-shaped historical input, and technical failure text remain in separate authorized audit/engineering surfaces. - Team-lead task summaries are a separate role-driven read projection, not an extension of dashboard, task, or ERP authority. An active leader with an enabled owned AgentBus channel is automatically subscribed to future stable manual and AgentBus outcomes for other non-admin employees. Routing comes from the current owner's latest valid inbound route or channel external-user reference, remains encrypted, fails closed when unavailable or stale, and never copies raw instructions, attachments, customer/traveller data, URLs, or technical errors. -- Authorization is enforced in server and service paths, not by navigation visibility. A denied or unresolved non-admin business route stops before parsing, plugin dispatch, and ERP execution; creator authorization is rechecked at confirmation and browser claim. +- Authorization is enforced in database, server, and service paths, not by navigation visibility. An administrator task-data-plane request fails before task storage or execution logic. A denied or unresolved employee business route stops before parsing, plugin dispatch, and ERP execution; assignee authorization is rechecked at confirmation and browser claim. - Each enabled AgentBus channel owns one active non-admin employee account. Inbound work uses that account and route allowlist, persists the same account as immutable task assignee, and is returned only to that account's executable feed. A team-lead channel may additionally carry its leader's lower-priority proactive summary outbox; those rows use explicit destination/conversation routing and never become executable task traffic. -- Each employee account has one expected ERP identity and at most one fresh browser execution worker. Mismatched ERP identity, concurrent fresh workers, unbound channels, or unassigned tasks fail closed. Browser claims, active-execution checks, and confirmed FIFO are serialized per immutable task assignee, so one account cannot block or occupy another account's queue. -- Administrator-wide task visibility is a read model, not an executable feed. Task SSE history/live events, browser claims, plugin-result ingestion, and browser cleanup commands are always scoped to the authenticated account matching `assigned_user_id`, including for administrators. -- Extension `0.5.167` is the current manually published/loaded plugin baseline. It retains an idle-proof and guarded-reload message protocol, but the active control plane has no extension-release tables, ECS host mapping, OSS publication endpoint, Cloud Assistant dispatcher, or platform trigger; required migration remains 018. +- Each employee account has one expected ERP identity and at most one fresh browser execution worker. The extension accepts ERP identity only from exactly one `#Lable_UserName` login node and normalized full equality; missing, duplicate, blank, substring-only, or unrelated body-text matches fail closed without returning the observed identity. Concurrent fresh workers, unbound channels, or unassigned tasks also fail closed. Browser claims, active-execution checks, and confirmed FIFO are serialized per immutable task assignee, so one account cannot block or occupy another account's queue. +- Administrators have no task read or execution model. Task lists/details, attachments, artifacts, lifecycle mutations, SSE history/live events, browser claims, plugin-result ingestion, and browser cleanup commands require a `team_lead` or `user` session matching `assigned_user_id`; the team-lead dashboard and notification outbox remain separate read projections. +- Extension `0.5.169` is the current manually published/loaded plugin baseline, and the five Skills plus operator instruction DOCX are at `0.5.126`. The extension retains an idle-proof and guarded-reload message protocol, but the active control plane has no extension-release tables, ECS host mapping, OSS publication endpoint, Cloud Assistant dispatcher, or platform trigger; required migration is 021. - Creator and manual input-turn attribution remain durable while business input stays encrypted at rest. Routine removal is reversible archive/restore. Separately confirmed force delete physically removes an authorized task regardless of lifecycle state, retains only a minimal non-content deletion audit marker, and cannot undo an ERP write that already occurred. - Unknown, ambiguous, unverified, or post-write-uncertain states fail closed; automatic retries must not create duplicate writes. - PostgreSQL is the sole required durable database/state middleware, and the production artifact provider is OSS. Redis, message queues, MongoDB, and search services are not runtime dependencies. -- Migrations through `020_leader_task_summary_notifications` must complete before the updated application starts; migration 019 remains intentionally absent after the extension-updater rollback. The current ACK topology starts with one application replica because AgentBus listeners and SSE emission are process-local; horizontal scale requires explicit coordination first. +- Migrations through `021_admin_task_data_plane_isolation` must complete before the updated application starts; migration 019 remains intentionally absent after the extension-updater rollback. Migration 021 removes legacy administrator task principals and enforces future management/task-plane separation. The current ACK topology starts with one application replica because AgentBus listeners and SSE emission are process-local; horizontal scale requires explicit coordination first. - Operational diagnostics are privacy-safe structured JSON on stdout/stderr. Docker owns bounded rotation; repository files and a second mutable log database are not log sinks. - In the trusted internal deployment, AgentBus roster attachment downloads may resolve to private/reserved addresses. Credential-free HTTPS, DNS resolution/pinning, redirect revalidation, size, timeout, and digest checks remain mandatory, and trusted channels/bridges own the network-input boundary. - Canonical project memory is updated only under Integration Gate; feature tasks write only their task-scoped records. @@ -49,6 +49,7 @@ Authenticated manual or account-bound AgentBus input is routed through task-scop - AUTH-001 - AUTH-002 - AUTH-003 +- AUTH-004 ## Last Updated diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index 0fc3b56..5b69c35 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -4,10 +4,14 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Integrated Through +- Source commit `a2378c8` from feature task `20260907-admin-task-data-plane-isolation-c3a7e91b`, integrated as `fd39347`, for the management-plane-only administrator role, task-data-plane denial at UI/HTTP/service/database boundaries, team-lead-only operations dashboard, and migration `021_admin_task_data_plane_isolation`; integration task `20260907-integrate-all-changes-9d2e7c41` accepted AUTH-004 and reconciled the administrator boundary. +- Source commit `9043ad6eda0deb2a620e1303467d1c3bd80374ed` from feature task `20260907-leader-kanban-all-members-73c9e1a4`, integrated as `03d0131`, for the assignee-based team-lead dashboard over all durably assigned manual and AgentBus tasks. +- Source commit `af9c90a3142e197493e80d74333af876c3bb947a` from feature task `20260907-ignore-extra-roster-fields-a6e4c9f2`, integrated as `9d1a6b4`, for required-field-only passenger-workbook normalization `v1.4.0`, ignored non-import columns, and synchronized Skill/business-instruction release `0.5.126`. +- Source commit `5b57df0e10fc6c6c0b2f9eeef300e36508055acc` from feature task `20260907-fix-erp-account-verification-4d8c2a71`, integrated as `8f70cba`, for unique-login-node exact ERP identity verification and synchronized extension `0.5.168`. - Source commit `0b3aa5c42d5810761dd3d6bc6deee1dc4af5fd00` from feature task `20260907-auto-leader-summary-routing-5e8c1a73` for automatic role-driven team-lead summaries, current-owner AgentBus route learning/fallback, read-only status UI, stale-route cancellation, and removal of the manual mutation endpoint; integration task `20260907-integrate-auto-leader-summary-9a4d2c61` revised AUTH-003 and canonical notification behavior. - Source commit `1a3ab63` from feature task `20260907-implement-leader-agentbus-copy-b7e31a94` for default-off team-lead task summaries over future manual and AgentBus outcomes, a separate encrypted/revisioned outbox, verified proactive AgentBus routing, administrator configuration/health UI, and migration 020; integration task `20260907-integrate-leader-summaries-84c1d7ea` accepted AUTH-003 and canonical notification boundaries. -- Correction commit `fe1cc2cddc29e4dead81e53c16d31bb71493602d` from integration task `20260903-backup-revert-extension-update-c71a4e92` preserved the complete former `0.5.167`/migration-019 stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, removed the central private-OSS/ECS automatic-update service architecture without rewriting history, and retained the exact Chrome extension `0.5.167` source/package on the active main line with migration 018. -- Merge commit `3224758` and integration task `20260903-finalize-extension-update-a6c4e192` remain historical records of the full-stack extension-update design. Only the plugin `0.5.167` release, adaptive entry readiness, and dormant plugin-side idle/reload safeguards remain active; the server orchestration is preserved on the backup branch only. +- Correction commit `fe1cc2cddc29e4dead81e53c16d31bb71493602d` from integration task `20260903-backup-revert-extension-update-c71a4e92` preserved the complete former `0.5.167`/migration-019 stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, removed the central private-OSS/ECS automatic-update service architecture without rewriting history, and retained exact extension `0.5.167` with migration 018 at that correction point. +- Merge commit `3224758` and integration task `20260903-finalize-extension-update-a6c4e192` remain historical records of the full-stack extension-update design. Adaptive entry readiness and dormant plugin-side idle/reload safeguards remain in the later `0.5.169` release; server orchestration is preserved on the backup branch only. - Commit `c4c469f4441d744627af2d34abe693b6783e833c` for the independently advanced remote deployment/extension line. - Commit `cd45ce17d0fcd25f7fa89ab9f8a391d3e904ecdf` for WeChat attachment correlation and privacy-safe server diagnostics. - Commit `161f90d09d6ad1368973b1a85d51059059495223` for trusted-intranet attachment compatibility and canonical reconciliation. @@ -35,7 +39,7 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Current Focus -Operate the repository's current `0.5.167` extension baseline and fixed-scope account model safely, bind each enabled AgentBus channel to one employee/ERP identity, provision narrow route grants, use explicit leadership-dashboard filters, and preserve Program/AI plus per-assigned-account ERP execution boundaries. Same-account tasks remain FIFO and single-active; distinct accounts are independent, and administrator or team-lead visibility never enters another account's executable event/result path. Active team leads with usable owned AgentBus routes automatically receive future privacy-bounded summaries; migration 020, manual extension reload, guarded product-search retry, service rollout, and any live AgentBus/WeChat canary remain separately authorized runtime work. Server-side automatic extension updating is not part of the active main line. +Operate the repository's current extension `0.5.169`, Skill/business-instruction `0.5.126`, roster normalizer `v1.4.0`, and migration-021 fixed-scope account model safely. Administrators manage accounts, channels, employee grants, parser routing, automation settings, and audit but never enter the task data plane. Team leads/users own normal task operations through immutable assignment; same-account work remains FIFO and single-active while distinct accounts are independent. Team leads alone receive the read-only assignee-based dashboard over assigned manual and AgentBus work and automatic future privacy-bounded summaries through usable owned AgentBus routes. Migration 021, manual extension reload, guarded product-search retry, service rollout, and any live AgentBus/WeChat canary remain separately authorized runtime work. Server-side automatic extension updating is not part of the active main line. ## Recently Completed @@ -59,20 +63,25 @@ Operate the repository's current `0.5.167` extension baseline and fixed-scope ac - 2026-09-02: Integrated extension `0.5.165`: scatter-plan creation and independent batch-order creation now try loaded product candidates, then the form's native non-empty `S_chanpinming` search, and finally one bounded empty-query compatibility reload. A user-authorized search-only ERP check returned exactly one target row in both forms without selecting or saving it; zero or multiple local matches continue to fail closed. - 2026-09-03: Accepted AUTH-002 and integrated account-scoped ERP queues. Each immutable assignee now owns one FIFO/single-active claim partition, different accounts no longer block one another, and executable SSE/results/cleanup commands are owner-only even when an administrator is signed in. - 2026-09-03: Restored explicit permanent force deletion as a separate operation from reversible archive/restore. It bypasses lifecycle-state gates, physically removes task-owned platform records, retains a minimal deletion audit marker, performs post-commit cleanup best effort, and warns that prior ERP effects are not rolled back. -- 2026-09-03: Backed up the complete adaptive-readiness and central extension-update stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, then removed the central OSS/ECS update service and migration 019 from `main` with normal history-preserving commits. After correcting an initially over-broad rollback, the active repository retains the exact extension `0.5.167` source/package and uses migration 018; the removed server architecture was never deployed by these tasks. +- 2026-09-03: Backed up the complete adaptive-readiness and central extension-update stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, then removed the central OSS/ECS update service and migration 019 from `main` with normal history-preserving commits. At that rollback point the repository retained exact extension `0.5.167` with migration 018; the plugin and schema later advanced independently without restoring the removed server architecture. - 2026-09-07: Integrated AUTH-003 and migration 020 for administrator-managed team-lead task summaries. Future stable manual/AgentBus outcomes for other non-admin employees project into a separate encrypted outbox and use the leader's verified AgentBus/WeChat target without changing task ownership, employee reply priority, or ERP execution authority. - 2026-09-07: Revised AUTH-003 so active team-lead identity plus an enabled owned AgentBus channel automatically activates both-source summaries. Routing uses only the current owner's latest valid inbound route or the channel external-user reference; channel rebind clears stale identity data, the settings API/UI is read-only, and all prior privacy, future-only, revision, priority, and no-ERP-authority boundaries remain. +- 2026-09-07: Advanced the synchronized Chrome extension to `0.5.168`; expected ERP identity is accepted only from one unique login account node with normalized exact equality, never from whole-page substring matching. +- 2026-09-07: Advanced the synchronized Chrome extension to `0.5.169`; uncertain ERP writes now direct manual read-only verification to the immutable task owner instead of an administrator who has no task-data-plane access. +- 2026-09-07: Advanced passenger-workbook normalization to `v1.4.0` and the five Skills plus operator instruction DOCX to `0.5.126`. Only required ERP source semantics participate in extraction; ordinary non-import columns are ignored and excluded from canonical TSV while active-content safety remains workbook-wide. +- 2026-09-07: Expanded the team-lead operations dashboard to every durably assigned manual and AgentBus task using immutable assignment as the employee dimension; unassigned historical AgentBus rows remain excluded. +- 2026-09-07: Accepted AUTH-004 and migration 021. Administrators are management-plane-only, cannot access task APIs, browser workers, task routes, dashboards, summaries, or task principals, and role promotion removes legacy executable bindings. ## In Progress - The standard database currently contains one administrator account and no non-administrator task grants. Multi-account operational smoke testing remains for an administrator-led staging window. -- Required migrations through `020_leader_task_summary_notifications`, employee ERP identities/channel bindings, extension `0.5.167`, account-scoped queue/routing changes, force-delete behavior, and the merged dashboard/automatic-notification runtime changes have not been applied to or restarted on the standard service in this integration task. No live automatic team-lead delivery canary was performed. +- Required migrations through `021_admin_task_data_plane_isolation`, employee ERP identities/channel bindings, extension `0.5.169`, account-scoped queue/routing changes, owner force-delete behavior, roster `v1.4.0`, and the merged dashboard/automatic-notification/administrator-isolation runtime changes have not been applied to or restarted on the standard service in this integration task. No live automatic team-lead delivery canary was performed. ## Next Recommended Steps -1. In an explicitly authorized staging/rollout window, back up PostgreSQL, apply all migrations through 020, restart the control plane, manually load extension `0.5.167`, verify its runtime handshake, configure employee ERP identities and channel bindings, and run the multi-cloud-PC/identity/failover plus account-queue matrix before production assurance. -2. Through the administrator UI, create representative team-lead and ordinary accounts, assign narrow task grants, and verify owner isolation, leadership dashboard reads, grant/revoke behavior, and denial prompts without ERP writes. -3. In the same authorized staging window, verify that an administrator receives no employee executable events/results, then force-delete disposable waiting and active employee tasks and confirm database absence plus cleanup only in the owning employee plugin. +1. In an explicitly authorized staging/rollout window, back up PostgreSQL, apply all migrations through 021, deploy the control plane and platform assets together, restart the service, manually load extension `0.5.169`, and verify readiness plus the exact-account handshake. +2. Through the administrator management UI, create representative team-lead and ordinary accounts, assign narrow task grants and channels, and verify that administrator task pages/APIs/workers fail closed while employee routes remain usable. +3. With separate team-lead and employee sessions, verify owner isolation, both-source leadership-dashboard reads, same-account FIFO, cross-account independence, mismatched ERP identity, worker conflict/failover, and owner-performed waiting/active force deletion without unintended ERP writes. 4. With explicit authorization, run a live read-only ERP verification of the shared-mother-plan `tid-only` whole-visitor export path. 5. With explicit authorization, perform ERP write verification for independent-order SGL/TWN and adult/child/leader headcount mappings. 6. With explicit external-send authorization, use one controlled team-lead channel to verify automatic current-owner route resolution, proactive `task.summary` handling, and stable-frame deduplication through AgentBus/WeChat, then observe one manual and one AgentBus task before wider assurance. @@ -81,8 +90,10 @@ Operate the repository's current `0.5.167` extension baseline and fixed-scope ac - Shared-mother-plan whole-visitor export has historical read evidence and static coverage but lacks a fresh authorized runtime ERP read verification. - Independent-order SGL/TWN and four headcount categories lack authorized current-version ERP write evidence. -- The standard service was last restarted before commits `3062ed5`, `b5f5847`, `cc09506`, `336ca6e`, `e4fd916`, and `d09b303`; its runtime schema, extension, account UI, queue/routing, force-delete, and dashboard behavior must not be represented as the newly integrated repository state until an authorized rollout. -- AgentBus account-worker routing still lacks a live two-employee/two-cloud-PC staging matrix covering mismatched ERP login, same-account device conflict, 90-second stale failover, same-account FIFO, cross-account independence, administrator executable-feed isolation, and both manual and automatic channel work. +- The standard service was last restarted before commits `3062ed5`, `b5f5847`, `cc09506`, `336ca6e`, `e4fd916`, `d09b303`, and the 2026-09-07 integration commits; its runtime schema, extension, account UI, queue/routing, owner force-delete, roster normalization, administrator isolation, and dashboard behavior must not be represented as the newly integrated repository state until an authorized rollout. +- AgentBus account-worker routing still lacks a live two-employee/two-cloud-PC staging matrix covering unique-node exact ERP identity, mismatched login, same-account device conflict, 90-second stale failover, same-account FIFO, cross-account independence, administrator task-data-plane denial, and both manual and automatic channel work. +- Administrator migration 021 and the team-lead dashboard's assigned manual/AgentBus scope have repository and disposable-database evidence but no deployed multi-role browser canary. +- The exact user-supplied workbook could not be replayed after the roster `v1.4.0` fix because its temporary shared-pasteboard file expired; synthetic regressions cover ignored populated identity-card and ordinary extra columns without preserving passenger data. - Lifecycle-independent force deletion has repository regression evidence but lacks an authorized runtime smoke test for waiting/active deletion, database absence, OSS cleanup, and owner-plugin-only cleanup. - A live internal AgentBus attachment verification remains separately unperformed. - Proactive team-lead `task.summary` delivery has repository, mock-WebSocket, and disposable-PostgreSQL evidence but no deployed AgentBus/WeChat canary; automatic current-owner route resolution remains unverified in the live bridge. @@ -92,8 +103,8 @@ Operate the repository's current `0.5.167` extension baseline and fixed-scope ac - Any ERP write, uncertain post-write state, automatic retry, or scope widening. - Passenger workbook normalization, encrypted attachment persistence, leader-contact projection, and native ERP row capacity. - AgentBus channels and their upstream bridge are now a trusted network boundary because attachment URLs may target internal HTTPS hosts. -- Account role changes, session revocation, creator-based task-route revocation, cross-user dashboard projection, and encrypted input audit are security-sensitive boundaries. -- AgentBus channel ownership, immutable task assignment, expected ERP identity, browser-worker freshness/failover, and administrator non-execution are security- and write-safety-sensitive boundaries. +- Account role changes, migration-021 principal cleanup/triggers, administrator task-plane denial, session revocation, creator-based task-route revocation, cross-source assignee-based dashboard projection, and encrypted input audit are security-sensitive boundaries. +- AgentBus channel ownership, immutable task assignment, unique-node exact expected ERP identity, browser-worker freshness/failover, and administrator management/task-plane separation are security- and write-safety-sensitive boundaries. - Account-scoped advisory locking, per-assignee FIFO queries, executable SSE/result routing, and irreversible force deletion are concurrency-, authorization-, and evidence-sensitive boundaries. - Team-lead automatic route derivation, stale-owner invalidation, encrypted projection/delivery rows, at-least-once stable-frame deduplication, privacy allowlisting, and non-retractable external delivery are authorization- and disclosure-sensitive boundaries. - Release synchronization across extension source, minimum platform version, mapping, ZIP, Skills, DOCX, and `dist/release-manifest.json`. diff --git a/.project-docs/30-worklog/task-history.md b/.project-docs/30-worklog/task-history.md index 0c49b32..80fe6c0 100644 --- a/.project-docs/30-worklog/task-history.md +++ b/.project-docs/30-worklog/task-history.md @@ -13,3 +13,4 @@ This is integrated history. Feature tasks write only their task-scoped records; | 2026-09-03 | Extension-update iteration backup and scoped rollback | Preserved exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2`, removed migration 019 and server-side automatic updating, and retained extension `0.5.167` plus migration 018 through non-force commits. | [Rollback task](tasks/20260903-backup-revert-extension-update-c71a4e92.md) | | 2026-09-07 | Team-lead AgentBus task summaries | Integrated default-off future-only summaries for other non-admin employees' manual/AgentBus outcomes through a separate encrypted outbox and verified proactive target, without changing task or ERP authority. | [Integration task](tasks/20260907-integrate-leader-summaries-84c1d7ea.md) | | 2026-09-07 | Automatic leader-summary routing correction | Replaced the duplicate administrator subscription form with role-driven activation and current-owner AgentBus route resolution while retaining future-only privacy and delivery boundaries. | [Integration task](tasks/20260907-integrate-auto-leader-summary-9a4d2c61.md) | +| 2026-09-07 | Exact identity, roster selection, leader oversight, and administrator isolation | Integrated extension `0.5.169`, roster normalizer `v1.4.0`/Skill `0.5.126`, assigned manual+AgentBus leadership reporting, AUTH-004, and migration 021; repository/runtime rollout remains separate. | [Integration task](tasks/20260907-integrate-all-changes-9d2e7c41.md) | diff --git a/.project-docs/30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md b/.project-docs/30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md new file mode 100644 index 0000000..7a67e39 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md @@ -0,0 +1,61 @@ +# Task: Integrate all pending changes and push main + +## Identity + +- Task ID: 20260907-integrate-all-changes-9d2e7c41 +- Mode: Integration +- Branch: codex/20260907-integrate-all-changes-9d2e7c41-integrate-all-changes +- Worktree: /Users/inmanx/Documents/lwltAPI-integrate-all-changes-9d2e7c41 +- Base commit: 6bdaa2a6e6b6006241ee324ad0e8736f79bae7fd +- Owner: codex +- Status: In Progress + +## Scope + +- Audit every local branch and linked worktree against current `main` and `origin/main`, preserving occupied or unrelated dirty worktrees. +- Integrate source commits `5b57df0`, `af9c90a`, `9043ad6`, and `a2378c8` for exact ERP identity, required-field-only roster normalization, cross-source leader dashboard visibility, and administrator task-data-plane isolation. +- Resolve overlapping control-plane documentation, dashboard query, authorization, release, and test changes semantically. +- Promote the accepted source outcomes into canonical project memory, run repository and artifact verification, then push the integrated tree to `origin/main` without force. + +## Intent And Constraints + +- The user explicitly authorized integrating all pending repository changes into the main branch and pushing the result. +- Preserve `AUTH-002` account-scoped execution and `AUTH-003` leader-summary privacy while applying the user-confirmed replacement of administrator task visibility with a management-plane-only administrator role. +- Keep the leadership dashboard read-only and team-lead-only, but include every durably assigned `manual` and `agentbus` task and use immutable assignment as the employee dimension. +- Preserve exact-account behavior from extension `0.5.168`, then publish synchronized extension `0.5.169` so uncertain-write recovery names the immutable task owner; preserve Skill/business-instruction `0.5.126`, roster normalizer `v1.4.0`, and required migration `021` as current baselines. +- Do not merge historical diagnosis, recovery, rollback, superseded, or patch-equivalent branches merely because their tips are not ancestors of `main`. +- Do not modify source task records. The source diffs are applied without their task-owned records; integration progress is recorded only in this task record and canonical documents. +- Do not read `.env`, run production migrations, deploy or restart services, reload extensions, access or write ERP, mutate runtime tasks/accounts/channels, or send external messages. + +## Outcome + +- Audited every local branch and linked worktree against `main`/`origin/main`. Integrated the four distinct pending product changes and left patch-equivalent, superseded, diagnostic, recovery, and rollback branches out of the mainline. +- Recovered the known administrator-isolation dirty worktree under formal task ownership, committed it as source commit `a2378c8`, and preserved the unrelated occupied local `main` worktree without stashing, resetting, cleaning, or modifying it. +- Applied the source outcomes as integration commits `8f70cba` (exact ERP identity), `9d1a6b4` (required-field-only roster import), `03d0131` (all durably assigned team-lead dashboard tasks), and `fd39347` (administrator management-plane isolation). The overlapping `control-plane/README.md` conflict was resolved semantically. +- Accepted `AUTH-004` and reconciled authorization, architecture, business rules, evidence, commitments, and current-state memory around management-plane-only administrators, immutable task ownership, and team-lead-only read access. +- Advanced the synchronized Chrome extension baseline to `0.5.169`, changed uncertain-write guidance to require the task-owning account, archived the superseded `0.5.168` release, and created `dist/ltjt-order-assistant-0.5.169.zip` with SHA-256 `00ad06a1640d36cfe7df8c9e52d677131793c70d493392b551b7ecbd965c854b`. +- Preserved Skill/business-instruction version `0.5.126`, roster normalizer `ltjt-passenger-roster-workbook-v1.4.0`, and required schema migration `021_admin_task_data_plane_isolation`. +- Source task records remained untouched; all integration-specific decisions and verification are recorded here. The prepared integration tree still requires its final non-force push and remote-head verification. + +## Verification + +- Passed focused source regressions: exact ERP identity `3/3`, account authorization plus roster normalization `27/27`, and team-lead dashboard `5/5`. +- Passed `node --run check:repo` (`10/10`) and `node --run check`. +- Passed `node --run test:control-plane` (`180/180`) and `node --run test:legacy` (`273/273`). The legacy suite was rerun successfully after correcting its expected synchronized extension version. +- Passed `node --run build` and direct JavaScript syntax checks for the changed extension/runtime files. +- Passed final focused static regressions for control-plane authorization and owner-confirmation wording (`55/55`) and lifecycle/release contracts (`59/59`). +- Passed all five official Skill validators. +- Passed extension ZIP integrity, manifest SHA-256 verification, and exact package/source file-set comparison for `0.5.169`. +- Rendered all 12 pages of `dist/老挝联泰AI指令表-0.5.126.docx` with the bundled document renderer and configured Chinese fonts; visual inspection found no missing glyphs, clipping, overlap, or broken layout. +- Passed `git diff --check`, JSON parsing, conflict-marker scanning, and the final active-tree scan for stale administrator-confirmation wording; the only matches are negative regression assertions. +- Passed final `check_project_docs.py` and task-scoped `check_doc_drift.py`; remote push verification remains pending the closing task-record update. + +## Follow-ups + +- Apply migration `021_admin_task_data_plane_isolation`, deploy/restart services, distribute/reload extension `0.5.169`, and perform live ERP/runtime verification only in a separately authorized rollout. +- Exact customer-workbook validation remains unavailable in this repository; required-field-only behavior is covered by synthetic workbook regressions. +- No additional distinct merge candidate remained after the branch/worktree audit. + +## Promotion Candidates + +- None recorded. diff --git a/.project-docs/40-domain/business-rules.md b/.project-docs/40-domain/business-rules.md index 52f7787..2d45820 100644 --- a/.project-docs/40-domain/business-rules.md +++ b/.project-docs/40-domain/business-rules.md @@ -6,16 +6,16 @@ - Manual and AgentBus tasks share the same 18 machine routes, task-scoped parser mode snapshot, and organization automation rules. AgentBus intake evaluates the bound employee account's route grants rather than an administrator or whichever browser is online. - The platform exposes one fixed deployment scope, not an organization-management product. Accounts use `admin`, `team_lead`, and `user` roles. - Passwords must be non-empty but have no application-level length restriction. First login and administrator password reset do not force a subsequent password change; users may still change passwords voluntarily, administrators may reset them, and password changes revoke existing sessions according to the account lifecycle contract. -- Administrators always hold all 18 manual business routes. Team leads and ordinary users start with no task grants, require explicit administrator allowlists, and may use normal task APIs only for their own manual tasks. -- A known ungranted route or a non-unique/unresolved route for a non-administrator fails before parsing, plugin dispatch, or ERP execution. Authorization is rechecked for supplemental input, attachments, confirmation, automatic confirmation, and browser claim. -- Team leads may read all manual account work only through the platform-operations dashboard. The dashboard is aggregate-first across task, person, original input, final output, time, task type, and completion state, with business-facing drill-through. Its five summary cards are display-only; the explicit task-result filter defaults to all results. Internal attention or waiting-for-input states remain unchanged in task storage but are presented and filtered as “进行中”; the leadership view exposes no separate “待跟进” category. It is not an audit log and never renders technical payloads, internal identifiers, machine-shaped historical input, or technical failure text; this visibility does not grant cross-user task mutation, artifacts, SSE, global settings, audit administration, or AgentBus access. +- Administrators are management-plane-only identities. They manage accounts, roles, passwords, sessions, employee route grants, AgentBus channels, parser routing, automation settings, and audit, but hold no business routes and cannot create, inspect, mutate, stream, claim, reconcile, archive, restore, force-delete, or submit results for tasks. +- Team leads and ordinary users start with no task grants, require explicit administrator allowlists, and may use normal task APIs only for manual or AgentBus tasks immutably assigned to themselves. A known ungranted route or a non-unique/unresolved employee route fails before parsing, plugin dispatch, or ERP execution. Authorization is rechecked for supplemental input, attachments, confirmation, automatic confirmation, and browser claim. +- Team leads may read all durably assigned manual and AgentBus work only through the platform-operations dashboard; administrators cannot access it. The dashboard uses immutable `assigned_user_id` as the employee dimension, excludes historical AgentBus rows without a reliable assignee, and is aggregate-first across task, person, original input, final output, time, task type, and completion state with business-facing drill-through. Its five summary cards are display-only; the explicit task-result filter defaults to all results. Internal attention or waiting-for-input states remain unchanged in task storage but are presented and filtered as “进行中”; the leadership view exposes no separate “待跟进” category. It is not an audit log and never renders technical payloads, internal identifiers, machine-shaped historical input, or technical failure text; this visibility does not grant cross-user task mutation, artifacts, SSE, global settings, audit administration, or AgentBus access. - Separately, every active team lead with an enabled owned AgentBus channel and a usable current-owner route automatically receives an organization-wide task-summary projection for future manual and AgentBus tasks assigned to other non-admin employees. Only stable completed, failed, cancelled, uncertain, and uncertain-then-resolved outcomes qualify. The route and summary payload are encrypted, history is not backfilled, role/channel/routing invalidation cancels unsent rows, employee replies retain priority, and the message never includes raw instructions, attachments, customer/traveller data, URLs, or technical errors. This notification grants no task mutation, executable event, confirmation, browser, reconciliation, or ERP authority. -- Creator and input-turn attribution are durable, business inputs remain encrypted at rest, and denial audit excludes plaintext. Archive/restore is the reversible routine removal path. Explicit force delete is a separate irreversible operation that may physically remove an authorized task in any lifecycle state, retains only a minimal non-content deletion audit marker, and cannot undo ERP effects already written or retract a task summary already accepted by AgentBus/WeChat. -- Each non-admin employee may carry one case-insensitively unique expected ERP account and one AgentBus channel. New manual and AgentBus tasks persist an immutable assignee; only that account may confirm, claim, reconcile, resume, or submit ERP execution results. Administrators manage and inspect but do not execute another assignee's work. -- A browser is execution-ready only when it is the account's sole fresh worker and the active ERP session matches the expected account. Concurrent fresh workers, identity mismatch, unbound channels, and historical unassigned AgentBus tasks fail closed; stale failover waits 90 seconds. Claim locking, active-execution detection, confirmed FIFO, and queue position are scoped to immutable `assigned_user_id`: the same account stays serialized while different accounts execute independently. -- Administrator-wide task visibility never grants execution routing. Executable SSE history/live events, browser claims, plugin-result ingestion, and force-delete browser cleanup commands are scoped to the authenticated account matching the task assignee, so an administrator page or plugin cannot receive or process an employee's task. +- Creator and input-turn attribution are durable, business inputs remain encrypted at rest, and denial audit excludes plaintext. Archive/restore is the owning employee's reversible routine removal path. Explicit owner force delete is a separate irreversible operation that may physically remove that employee's task in any lifecycle state, retains only a minimal non-content deletion audit marker, and cannot undo ERP effects already written or retract a task summary already accepted by AgentBus/WeChat. Administrators cannot invoke task removal. +- Each non-admin employee may carry one case-insensitively unique expected ERP account and one AgentBus channel. New manual and AgentBus tasks persist an immutable assignee; only that account may confirm, claim, reconcile, resume, or submit ERP execution results. Administrators manage the account and channel configuration but cannot inspect or execute the employee's tasks. +- A browser is execution-ready only when it is the account's sole fresh worker and the active ERP session proves the expected account from exactly one `#Lable_UserName` login node by Unicode/whitespace/case-normalized full equality. Missing, duplicate, blank, substring-only, or unrelated page-text matches fail closed without exposing the observed account. Concurrent fresh workers, unbound channels, and historical unassigned AgentBus tasks also fail closed; stale failover waits 90 seconds. Claim locking, active-execution detection, confirmed FIFO, and queue position are scoped to immutable `assigned_user_id`: the same account stays serialized while different accounts execute independently. +- Administrators are rejected from the task data plane at the database, service, route, and UI boundaries. Executable task reads, SSE history/live events, browser claims, plugin-result ingestion, and force-delete browser cleanup commands require a team-lead/user session matching the task assignee. - The two passenger-list import routes are Program-only and wait for exactly one `.xls` or `.xlsx` attachment before deterministic normalization. -- Passenger workbooks must contain exactly one complete ERP-semantic header within rows 1–100. The header may be on row 1 or follow metadata, column order is arbitrary, and only the finite approved source/ERP aliases—including `NAME`, `证件号码`, `签发日`, and `身份证`—are mapped. Unknown or unheaded data columns, duplicate semantic fields, multiple candidate headers, and non-passport identity data fail closed; the internal 13-column canonical TSV contract remains unchanged. +- Passenger workbooks must contain exactly one complete ERP-semantic header within rows 1–100. The header may be on row 1 or follow metadata, column order is arbitrary, and only the finite approved aliases for the 12 required source semantics are selected. Identity-card, age, source document-type, hidden/local-formula, unheaded, and other ordinary non-import columns are ignored for row detection and selected-value validation and are never copied into the internal 13-column canonical TSV; canonical `证件类型` remains the implicit constant `护照`. Missing/duplicate required semantics, multiple candidate headers, unsafe selected formulas/results, non-contiguous selected rows, macros, external relationships, hyperlinks, and external formulas fail closed. - A WeChat attachment card is transport placeholder text, not file content. Only a structured `payload.attachments[]` entry can resume a roster task; missing metadata fails before ingestion and leaves the original task in `awaiting_attachment` instead of creating a new task. - The trusted internal deployment accepts credential-free HTTPS roster attachment URLs whose host is internal, private/reserved IPv4/IPv6, or localhost. DNS pinning, redirect revalidation, download timeout, byte limits, declared-size checks, and optional SHA-256 verification remain mandatory. - AgentBus attachment diagnostics may record stage, address count/family, status, byte count, code, outcome, and duration, but never URL, hostname, IP, file name, bytes, message text, or roster values. diff --git a/.project-docs/40-domain/glossary.md b/.project-docs/40-domain/glossary.md index 591feab..e83d1f0 100644 --- a/.project-docs/40-domain/glossary.md +++ b/.project-docs/40-domain/glossary.md @@ -10,4 +10,7 @@ | Program-only | Route must use the deterministic parser and may not fall back to AI | Applies to both passenger-list routes | | fresh requery | Read-only ERP verification performed after an action | Required except where an action-specific explicit-success credential is accepted | | no ERP write | Evidence-backed result that the write boundary was not crossed | Must not be inferred from an unknown post-submit failure | +| management plane | Account, channel, parser-routing, automation-setting, and audit administration available to `admin` | Excludes every business-task API, dashboard, browser worker, and task principal | +| task data plane | Business-task creation, reads, inputs, lifecycle mutations, events, browser execution, results, artifacts, and deletion | Available only to `team_lead`/`user`; normal operations require immutable ownership | +| immutable assignee | The durable `assigned_user_id` that owns task execution and employee attribution | Drives owner-only operations, per-account FIFO, and the cross-source team-lead dashboard | | Promotion Candidate | Task-scoped proposal for durable canonical memory | Accepted only through Integration Gate | diff --git a/.project-docs/50-evidence/evidence-index.md b/.project-docs/50-evidence/evidence-index.md index 6f25a8a..3d7df9a 100644 --- a/.project-docs/50-evidence/evidence-index.md +++ b/.project-docs/50-evidence/evidence-index.md @@ -20,9 +20,12 @@ Use this index for searchable, traceable evidence records. | 2026-09-02 | Leadership-dashboard filtering and summary interaction | Repository and focused regression verified; merged runtime not restarted | [Integration record](../30-worklog/tasks/20260902-integrate-all-push-c93a7f21.md) | Single-connection bounded reads, SQL prefiltering, selective hydration, 20-row paging, cancellation/timeout feedback, and display-only metric cards with explicit filters passed combined regression. | | 2026-09-02 | Native ERP product search for ordering forms | Root cause and live search-only behavior verified; repository/release verified; extension not reloaded | [Integration task](../30-worklog/tasks/20260902-integrate-product-search-3b7f6a20.md) | Both `plan_add.asp` and `orders_adds.asp` returned exactly one target product for the full keyword with radios left unchecked and no save; extension `0.5.165` now uses native non-empty search before its bounded empty-query fallback while retaining deterministic unique matching. | | 2026-09-03 | Account-scoped ERP queues, assignee-only executable routing, and force delete | Repository and full regression verified; runtime not deployed or mutated | [Integration task](../30-worklog/tasks/20260903-finalize-account-routing-7c4e2a91.md) | Source task `20260902-per-account-queue-hard-delete-a6d9f2c1` replaced global head-of-line blocking with per-assignee FIFO/advisory locks, isolated SSE/plugin-result/browser-command routing from administrator read visibility, and separated reversible archive from lifecycle-independent physical deletion. | -| 2026-09-03 | Adaptive ERP readiness and central extension host updates | Mixed disposition: plugin/release retained; server architecture reverted before production rollout | [Original integration task](../30-worklog/tasks/20260903-finalize-extension-update-a6c4e192.md) | Exact extension `0.5.167` source/package and adaptive readiness remain active. Migration 019 and central private-OSS/ECS orchestration are recoverable only at exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2`. | -| 2026-09-03 | Extension-update iteration scoped rollback | Backup ref verified; `0.5.167` retained; server/migration rollback and regression rechecked | [Rollback task](../30-worklog/tasks/20260903-backup-revert-extension-update-c71a4e92.md) | The full stack was backed up before normal non-force commits removed server-side automatic updating and migration 019; active main keeps extension `0.5.167` and migration 018 without rewriting Git history. | +| 2026-09-03 | Adaptive ERP readiness and central extension host updates | Mixed disposition: plugin/release retained at rollback; server architecture reverted before production rollout | [Original integration task](../30-worklog/tasks/20260903-finalize-extension-update-a6c4e192.md) | Exact extension `0.5.167` and adaptive readiness were retained when migration 019 and central private-OSS/ECS orchestration moved to backup commit `b2e33e2`; the active plugin later advanced independently. | +| 2026-09-03 | Extension-update iteration scoped rollback | Backup ref verified; server/migration rollback and regression rechecked | [Rollback task](../30-worklog/tasks/20260903-backup-revert-extension-update-c71a4e92.md) | The full stack was backed up before normal non-force commits removed server-side automatic updating and migration 019; the rollback retained extension `0.5.167` and migration 018 without rewriting Git history. | | 2026-09-07 | Team-lead task-summary projection and proactive AgentBus delivery | Repository and disposable-PostgreSQL verified; not deployed or externally sent | [Feature task](../30-worklog/tasks/20260907-implement-leader-agentbus-copy-b7e31a94.md) | Migration 020, future-only encrypted projection, privacy allowlist, stale-uncertainty supersession, employee-first outbound priority, stable proactive frame IDs, no `reply_to`, echo rejection, and administrator controls passed full regression; exact AgentBus/WeChat routing still needs an authorized canary. | +| 2026-09-07 | Exact ERP account identity and extension `0.5.169` | Repository, focused identity, package/source, and release hashes verified; not loaded or deployed | [Integration task](../30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md) | One unique `#Lable_UserName` node plus normalized full equality is now the only accepted identity proof; missing, duplicate, blank, substring-only, and unrelated page-text matches fail closed without exposing the observed account. Uncertain writes direct manual read-only verification to the immutable task owner. | +| 2026-09-07 | Required-field-only passenger roster normalization `v1.4.0` | Synthetic/parser, Skill-package, release, and 12-page DOCX rendering verified; exact uploaded file unavailable for replay | [Integration task](../30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md) | The 12 required source semantics alone drive extraction and validation; ordinary non-import columns are ignored and excluded from canonical TSV, while workbook-wide active-content checks remain. | +| 2026-09-07 | Assignee-based leader dashboard and administrator task-plane isolation | Repository and disposable-PostgreSQL verified; runtime rollout not performed | [Integration task](../30-worklog/tasks/20260907-integrate-all-changes-9d2e7c41.md) | Team leads see assigned manual and AgentBus work through the bounded read model; migration 021 removes and rejects administrator task principals, while UI/HTTP/service guards deny administrator task access. | ## When To Add Evidence diff --git a/.project-docs/80-commitments/commitments.md b/.project-docs/80-commitments/commitments.md index dbcad57..96e72ce 100644 --- a/.project-docs/80-commitments/commitments.md +++ b/.project-docs/80-commitments/commitments.md @@ -7,10 +7,10 @@ Track future-facing memory: promised follow-ups, unfinished loops, timed checks, | 2026-08-28 | Verify shared-mother-plan `tid-only` whole-visitor export against the current runtime ERP path. | Explicit user authorization for ERP read access | Future authorized task | Pending authorization | Run read-only source and artifact checks without external delivery. | | 2026-08-28 | Verify independent-order SGL/TWN and adult/child/leader headcount mappings with real ERP writes. | Explicit user authorization for controlled ERP writes | Future authorized task | Pending authorization | Use reversible values and action-specific requery evidence. | | 2026-08-28 | Resolve AgentBus OSS attachment rejection caused by private/reserved local DNS answers. | User scheduled integration and confirmed the environment is trusted internal networking | Integration task `20260831-integrate-server-diagnostics-8b42c6d1` | Completed in repository | Deploy/restart and run one live internal attachment verification only under separate authorization. | -| 2026-09-02 | Roll out and stage-test AgentBus account workers, account-scoped queues, and force deletion. | Explicit authorization for database backup/migration, service restart, extension reload, account/channel configuration, staging traffic, and disposable task mutation | Future authorized rollout task | Pending authorization | Apply migration 018 and extension `0.5.165`; verify two employee accounts/cloud PCs, ERP identity mismatch, same-account worker conflict/FIFO, cross-account independence, 90-second failover, administrator executable-feed isolation, manual/AgentBus routing, and waiting/active force-delete cleanup. | -| 2026-09-02 | Verify the integrated native product-search execution path. | Explicit authorization for extension reload and a guarded ERP preflight/retry | Future authorized rollout task | Pending authorization | Load extension `0.5.165`, confirm the runtime handshake, then verify deterministic product selection and normal write gates without automatically retrying the earlier failed task. | -| 2026-09-03 | Bootstrap and canary the central extension-update channel. | Former rollout plan for reverted server-side `EXT-001` architecture | None while reverted | Cancelled by user rollback | Extension `0.5.167` remains the current manual plugin release. Do not deploy migration 019 or the removed server updater from `main`; consult `codex/backup-extension-update-20260903-b2e33e2` only if a future explicit decision revives that architecture. | -| 2026-09-07 | Deploy and canary team-lead task-summary notifications. | Explicit authorization for database backup/migration, service restart, channel/target configuration, and controlled external AgentBus/WeChat delivery | Future authorized rollout task | Pending authorization | Apply migrations through 020, verify one exact team-lead route, confirm `task.summary` routing and stable-ID deduplication, then observe one manual and one AgentBus task before wider enablement. | +| 2026-09-02 | Roll out and stage-test AgentBus account workers, account-scoped queues, administrator isolation, and owner force deletion. | Explicit authorization for database backup/migration, service restart, extension reload, account/channel configuration, staging traffic, and disposable task mutation | Future authorized rollout task | Pending authorization | Apply migrations through 021 and extension `0.5.169`; verify two employee accounts/cloud PCs, unique-node exact ERP identity and mismatch, same-account worker conflict/FIFO, cross-account independence, 90-second failover, administrator task-API denial, manual/AgentBus routing, and owner-performed waiting/active force-delete cleanup. | +| 2026-09-02 | Verify the integrated native product-search execution path. | Explicit authorization for extension reload and a guarded ERP preflight/retry | Future authorized rollout task | Pending authorization | Load current extension `0.5.169`, confirm the runtime handshake, then verify deterministic product selection and normal write gates without automatically retrying the earlier failed task. | +| 2026-09-03 | Bootstrap and canary the central extension-update channel. | Former rollout plan for reverted server-side `EXT-001` architecture | None while reverted | Cancelled by user rollback | Extension `0.5.169` is the current manual plugin release. Do not deploy migration 019 or the removed server updater from `main`; consult `codex/backup-extension-update-20260903-b2e33e2` only if a future explicit decision revives the archived `0.5.167` server-update architecture. | +| 2026-09-07 | Deploy and canary team-lead task-summary notifications. | Explicit authorization for database backup/migration, service restart, employee channel binding, and controlled external AgentBus/WeChat delivery | Future authorized rollout task | Pending authorization | Apply migrations through 021, verify one exact team-lead current-owner route, confirm `task.summary` routing and stable-ID deduplication, then observe one manual and one AgentBus task before wider enablement. | ## Use diff --git a/LianSyn-platform/app.js b/LianSyn-platform/app.js index ff2734b..860d1a0 100644 --- a/LianSyn-platform/app.js +++ b/LianSyn-platform/app.js @@ -100,7 +100,7 @@ const persistedExtensionResultVersions = new Map(); let taskCreateInProgress = false; const AUTO_HANDOFF_RETRY_MS = 30_000; -const REQUIRED_EXTENSION_VERSION = '0.5.168'; +const REQUIRED_EXTENSION_VERSION = '0.5.169'; const MANUAL_HANDOFF_LABEL = '确认并提交到 ERP 插件'; const RETRY_HANDOFF_LABEL = '继续提交到 ERP 插件'; const RECONCILE_LABEL = '只读回查 ERP 现有结果'; diff --git a/agent设计规范/agentbus-reply-contract.md b/agent设计规范/agentbus-reply-contract.md index 33ebc7b..19a0931 100644 --- a/agent设计规范/agentbus-reply-contract.md +++ b/agent设计规范/agentbus-reply-contract.md @@ -18,7 +18,7 @@ 摘要只包含员工账号、登记业务名称、归一化业务状态、公共任务编号、上海时区提交时间,以及成功回执中经过白名单提取的团号/订单号。不得包含原始或补充指令、客户/游客/联系人信息、附件、Agent/插件/ERP 技术错误、堆栈、URL、token、内部 UUID、生命周期细节或未验证的执行结果。失败只使用统一业务文案;写入不确定不得包装成完成。 -订阅的收件地址、微信会话 ID 和每条待发正文必须字段加密;列表、审计和日志只展示截短 SHA-256 指纹、投递 ID、任务公共编号、状态和次数,不回显目标或正文。发送采用耐久 outbox、`FOR UPDATE SKIP LOCKED` 领取、短租约恢复和指数退避;WebSocket send 成功只表示已经交给 AgentBus,不证明微信最终展示。该链路是至少一次语义,极少情况下可能重复;已经到达微信的摘要无法由平台撤回,管理员界面和永久删除确认必须明确提示这一点。 +订阅的收件地址、微信会话 ID 和每条待发正文必须字段加密;列表、审计和日志只展示截短 SHA-256 指纹、投递 ID、任务公共编号、状态和次数,不回显目标或正文。发送采用耐久 outbox、`FOR UPDATE SKIP LOCKED` 领取、短租约恢复和指数退避;WebSocket send 成功只表示已经交给 AgentBus,不证明微信最终展示。该链路是至少一次语义,极少情况下可能重复;已经到达微信的摘要无法由平台撤回,管理员的渠道状态界面和任务归属人的永久删除确认必须明确提示这一点。 ## 归属和执行路由 diff --git a/agent设计规范/business-adaptation-registry.md b/agent设计规范/business-adaptation-registry.md index a4998b9..a1e648b 100644 --- a/agent设计规范/business-adaptation-registry.md +++ b/agent设计规范/business-adaptation-registry.md @@ -1,6 +1,6 @@ # 业务适配登记表 -这是跨会话和交付的业务入口。它回答三个问题:业务人员怎么输入、ERP 怎么执行、Skill 在哪里维护。运营统一复制入口见[运营业务 AI 输入模板总表](templates/business-input-templates.md),AI 业务路由参考见 [business-behavior-registry.md](business-behavior-registry.md),18 项确定性解析的指令、字段、action 和版本唯一机器源见 [`control-plane/src/business-routes.ts`](../control-plane/src/business-routes.ts)。该机器路由、任务级解析模式快照和组织全自动化规则对手工与 AgentBus 新任务全局共用,来源只负责输入和回执适配;AgentBus 渠道必须绑定一个员工平台账号,并使用该账号的业务白名单、任务归属、唯一云电脑 worker 和 ERP 身份门禁。ERP 领取队列按不可变的任务归属账号分别保持 FIFO 与单活跃执行,不同账号互不阻塞;管理员跨账号查看权限不得进入员工任务的可执行事件、插件回执或浏览器清理链路。 +这是跨会话和交付的业务入口。它回答三个问题:业务人员怎么输入、ERP 怎么执行、Skill 在哪里维护。运营统一复制入口见[运营业务 AI 输入模板总表](templates/business-input-templates.md),AI 业务路由参考见 [business-behavior-registry.md](business-behavior-registry.md),18 项确定性解析的指令、字段、action 和版本唯一机器源见 [`control-plane/src/business-routes.ts`](../control-plane/src/business-routes.ts)。该机器路由、任务级解析模式快照和组织全自动化规则对获授权员工的手工与 AgentBus 新任务全局共用,来源只负责输入和回执适配;AgentBus 渠道必须绑定一个员工平台账号,并使用该账号的业务白名单、任务归属、唯一云电脑 worker 和唯一登录节点精确 ERP 身份门禁。ERP 领取队列按不可变的任务归属账号分别保持 FIFO 与单活跃执行,不同账号互不阻塞;管理员只进入账号、渠道、解析策略、自动化设置和审计管理面,不创建、查看、修改、领取或删除业务任务。 ## 状态定义 diff --git a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md index f1def31..f522d16 100644 --- a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md +++ b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md @@ -2,7 +2,7 @@ ## 当前基线 -- Chrome 插件:`0.5.168` +- Chrome 插件:`0.5.169` - Agent Prompt:`ltjt-agent-prompt-v1.8-independent-headcount-categories` - 生命周期契约:`ltjt-lifecycle-v2.9-roster-leader-contact-2026-08` - 五个 Skill:`0.5.126`;运营 DOCX:`0.5.126` @@ -11,6 +11,7 @@ - `0.5.166` 在散拼母团列表入口加入立即检查、100ms 条件轮询和 15 秒总超时;每次探测都重新取得当前主 iframe document,按钮一旦可用便立即继续。该等待只发生在点击前,不固定拖慢快速页面,也不触发业务写入重试。 - `0.5.167` 保留插件侧的空闲证明和受控重载安全协议,并继续包含 `0.5.166` 的散拼入口自适应等待。中央服务私有 OSS/ECS 云助手编排及迁移 019 已按用户决定从主线撤回,因此这些插件更新消息在当前主线没有服务端触发方,属于休眠能力;插件仍按现有人工发布/加载流程使用。 - `0.5.168` 将 ERP 身份门禁从整页子串搜索收紧为唯一 `#Lable_UserName` 登录节点的规范化精确全等;缺失、重复、空白、子串或其他页面文字命中均不再让云电脑进入可执行状态,观察到的账号文本不离开扩展。 +- `0.5.169` 保留全部执行门禁,并将 ERP 写入不确定后的人工只读核验责任明确绑定到任务归属账号;管理员仍完全不进入任务数据面。 - 名单工作簿 normalizer `v1.4.0` 与业务输入/Skill `0.5.126` 改为只选择 12 个必需源字段;身份证、年龄、源证件类型及其他普通额外列不参与行识别、字段校验或 canonical 输出。必需字段完整性、宏/外链、全局超链接和外部公式等安全门槛保持失败关闭。 运行中的浏览器版本必须实时握手确认。当前制品文件名和 SHA-256 只看 [`../../../dist/release-manifest.json`](../../../dist/release-manifest.json),不从历史日志推断。 @@ -73,7 +74,7 @@ - route preparation 只以一次性不透明 token 把已精确选中的 Document 交给后台 frame discovery;token 不进入业务 operation、日志或 ERP 请求,正式 preflight 仍再次执行完整引用、状态与 ownership 门禁。 - 除名单录入外,写入后必须同时有明确服务端响应和 fresh requery;HTTP 200、弹窗或文件源响应不能单独证明完成。名单录入必须先通过附件、对象身份、覆盖确认、游客与领队完整写前投影,并且只以父表单 ERP 明确成功响应作为完成证据;不做写后逐行回查或自动名单对账。 - 目标值已等于当前值时不派发字段事件,`write_attempted=false`。 -- 其他业务写入不确定时先只读回查同一 execution,禁止自动重试;仍无法确认时面向用户明确显示“请勿重复提交,等待管理员核验”。名单若没有取得 ERP 明确成功响应则不宣称成功,也不自动重提。 +- 其他业务写入不确定时先由任务归属账号只读回查同一 execution,禁止自动重试;仍无法确认时面向用户明确显示“请勿重复提交,等待人工核验”。名单若没有取得 ERP 明确成功响应则不宣称成功,也不自动重提。 ## 正式放行条件 diff --git a/archive/releases/2026-09-07/README.md b/archive/releases/2026-09-07/README.md index 4584236..3e8a34f 100644 --- a/archive/releases/2026-09-07/README.md +++ b/archive/releases/2026-09-07/README.md @@ -4,6 +4,8 @@ - `release-manifest-0.5.167.json`:收紧 ERP 登录账号身份识别前的历史清单快照。 - `ltjt-order-assistant-0.5.167.zip`:被 `0.5.168` 的唯一登录节点精确账号匹配替代;保留用于恢复和追溯。 +- `release-manifest-0.5.168.json`:统一不确定任务人工复核责任人前的历史清单快照。 +- `ltjt-order-assistant-0.5.168.zip`:被 `0.5.169` 的任务归属账号复核文案替代;保留用于恢复和追溯。 - `release-manifest-0.5.168-skills-0.5.125.json`:名单额外字段白名单提取前的 `0.5.168 / 0.5.125 / 0.5.125` 历史清单快照。 - `lwlt-*-0.5.125.skill`:被 `0.5.126` Skill 发布基线替代;其中 lifecycle 包仍记录旧的额外列失败关闭规则。 - `老挝联泰AI指令表-0.5.125.docx`:被 `0.5.126` 的名单必需字段白名单说明替代。 diff --git a/dist/ltjt-order-assistant-0.5.168.zip b/archive/releases/2026-09-07/ltjt-order-assistant-0.5.168.zip similarity index 100% rename from dist/ltjt-order-assistant-0.5.168.zip rename to archive/releases/2026-09-07/ltjt-order-assistant-0.5.168.zip diff --git a/archive/releases/2026-09-07/release-manifest-0.5.168.json b/archive/releases/2026-09-07/release-manifest-0.5.168.json new file mode 100644 index 0000000..0b3f0c2 --- /dev/null +++ b/archive/releases/2026-09-07/release-manifest-0.5.168.json @@ -0,0 +1,69 @@ +{ + "manifest_version": 1, + "generated_on": "2026-09-07", + "baselines": { + "chrome_extension": "0.5.168", + "skills": "0.5.126", + "business_instruction_docx": "0.5.126", + "agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories" + }, + "artifacts": [ + { + "kind": "chrome_extension", + "version": "0.5.168", + "path": "dist/ltjt-order-assistant-0.5.168.zip", + "source": "chrome-extension/ltjt-order-assistant", + "sha256": "2432a882f2fbdcf28bfb6bb8a7fead55986297f86d4cf4ab8e12ea373c72518c" + }, + { + "kind": "skill", + "name": "lwlt-arrangement", + "version": "0.5.126", + "path": "dist/lwlt-arrangement-0.5.126.skill", + "source": "agent设计规范/skills/lwlt-arrangement", + "sha256": "83770befe3a8e4048eacaeacb567c5139bf8a0b3a49f2b1513c26383422f2a9c" + }, + { + "kind": "skill", + "name": "lwlt-confirmation", + "version": "0.5.126", + "path": "dist/lwlt-confirmation-0.5.126.skill", + "source": "agent设计规范/skills/lwlt-confirmation", + "sha256": "543507ed8b68c183d2df6722061b0e927ebb728de4bf254d15f83311c9264018" + }, + { + "kind": "skill", + "name": "lwlt-lifecycle", + "version": "0.5.126", + "path": "dist/lwlt-lifecycle-0.5.126.skill", + "source": "agent设计规范/skills/lwlt-lifecycle", + "sha256": "fff3879d9a4143c34ae51e091b91411e55382ad3f5d77c99d6202a005b1ddbd9" + }, + { + "kind": "skill", + "name": "lwlt-newbooking", + "version": "0.5.126", + "path": "dist/lwlt-newbooking-0.5.126.skill", + "source": "agent设计规范/skills/lwlt-newbooking", + "sha256": "5eb6a7bf5649a0fcee3fbee488a124e1b1d018a642a3a49ebb5439ccf20ccc2f" + }, + { + "kind": "skill", + "name": "lwlt-updating", + "version": "0.5.126", + "path": "dist/lwlt-updating-0.5.126.skill", + "source": "agent设计规范/skills/lwlt-updating", + "sha256": "3bd665207649cbb8e0e5ebb012c916720201fe160eea62bccdf1c3a1f0275d1d" + }, + { + "kind": "business_instruction_docx", + "version": "0.5.126", + "path": "dist/老挝联泰AI指令表-0.5.126.docx", + "source": "agent设计规范/templates/business-input-templates.md", + "builder": "tools/build_business_instruction_docx.py", + "sha256": "052611d9b700afe66b02a9b3e3b456fc245ac46541d338980f2fa4ff2e41de14", + "source_sha256": "3ea8efd5174c0d4ab59972fb30fac2f8c6dfe7308f4e3fdb6e5b5e7c9c76258b", + "builder_sha256": "c162884210da22e3b78368749b66f1f177df5e9fc6155f4fd9954bd516d187f1" + } + ] +} diff --git a/chrome-extension/ltjt-order-assistant/README.md b/chrome-extension/ltjt-order-assistant/README.md index 9cdceb6..7e7ebc4 100644 --- a/chrome-extension/ltjt-order-assistant/README.md +++ b/chrome-extension/ltjt-order-assistant/README.md @@ -11,9 +11,13 @@ Chrome Manifest V3 扩展,在用户已登录的 LTJT ERP 页面内执行经过 ## 当前版本 -当前源码版本为 `0.5.168`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 +当前源码版本为 `0.5.169`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 -0.5.168 当前重点: +0.5.169 当前重点: + +- ERP 写入结果不确定时,扩展停止自动重试并明确要求任务归属账号做人工只读核验,不再把责任错误指向无任务数据面权限的管理员。 + +继续保留 0.5.168 的 ERP 精确身份门禁: - ERP 登录身份只从当前主页面唯一的 `#Lable_UserName` 节点读取,并与平台绑定身份做 Unicode、空白和大小写规范化后的精确全等比较。缺失、重复、空白或仅为子串时都不再执行;不再用整页业务文字猜测账号。 - 扩展仍只向平台返回账号是否存在、是否唯一和是否匹配,不回传 ERP 页面显示的账号文本。 diff --git a/chrome-extension/ltjt-order-assistant/background.js b/chrome-extension/ltjt-order-assistant/background.js index b54bf29..e7afc10 100644 --- a/chrome-extension/ltjt-order-assistant/background.js +++ b/chrome-extension/ltjt-order-assistant/background.js @@ -2664,7 +2664,7 @@ async function executeLifecycleOperation(taskId, operation, operationPlan) { }); await publish(taskId, executionOperation, 'lifecycle_reconciliation', live, { status: 'execution_uncertain', - message: 'ERP 写入已发起,但自动只读复核仍无法确认最终结果。系统已停止且不会自动重试;请勿重复提交同一任务,等待管理员只读核验。', + message: 'ERP 写入已发起,但自动只读复核仍无法确认最终结果。系统已停止且不会自动重试;请勿重复提交同一任务,等待任务归属账号人工只读核验。', operation_plan: publicPlan, no_erp_write: false, write_attempted: true, @@ -3524,7 +3524,7 @@ async function reconcileLifecycleTask(taskId) { ok: false, status: 'reconciliation_pending', task_id: rootId, - message: `${readOnly.message} 没有重试 ERP 写入;请勿重复提交同一任务,任务继续等待管理员核验。`, + message: `${readOnly.message} 没有重试 ERP 写入;请勿重复提交同一任务,任务继续等待归属账号人工核验。`, blockers: readOnly.blockers || [], requery: readOnly.verification?.requery || null }; diff --git a/chrome-extension/ltjt-order-assistant/inpage.js b/chrome-extension/ltjt-order-assistant/inpage.js index ca711ab..e8968eb 100644 --- a/chrome-extension/ltjt-order-assistant/inpage.js +++ b/chrome-extension/ltjt-order-assistant/inpage.js @@ -6118,7 +6118,7 @@ } window.LTJTOrderAssistant = { - version: '0.5.168', + version: '0.5.169', resolveNativeListSearchValues, lookupKeywordMatchesText, inspectLifecycleSearchCriteria: lifecycleSearchCriteria, diff --git a/chrome-extension/ltjt-order-assistant/manifest.json b/chrome-extension/ltjt-order-assistant/manifest.json index 1679680..1a434d5 100644 --- a/chrome-extension/ltjt-order-assistant/manifest.json +++ b/chrome-extension/ltjt-order-assistant/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "联泰下单助手", - "version": "0.5.168", + "version": "0.5.169", "description": "在已登录 LTJT ERP 页面内规划并受控执行联泰 ERP 业务操作。", "permissions": [ "activeTab", diff --git a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js index a4be622..4109694 100644 --- a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js +++ b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js @@ -944,7 +944,7 @@ window.LTJTOrderAssistant = { ...(window.LTJTOrderAssistant || {}), - version: '0.5.168', + version: '0.5.169', openTeamBatchForm, pingTeamBatchFrame, preflightTeamBatchNative, diff --git a/control-plane/README.md b/control-plane/README.md index 7464791..3715c32 100644 --- a/control-plane/README.md +++ b/control-plane/README.md @@ -5,7 +5,7 @@ ## 服务边界 - PostgreSQL 是任务、事件、幂等、审计和回查状态的唯一事实源。 -- 平台账号使用 `admin`(管理员)、`team_lead`(组长)和 `user`(普通用户)三种固定角色登录;服务端会话使用 HttpOnly/Secure/SameSite Cookie。管理员维护账号、角色、状态、密码重置、会话撤销和可执行任务类型;平台不提供组织或租户选择。 +- 平台账号使用 `admin`(管理员)、`team_lead`(组长)和 `user`(普通用户)三种固定角色登录;服务端会话使用 HttpOnly/Secure/SameSite Cookie。管理员维护账号、角色、状态、密码重置、会话撤销和员工可执行任务类型,但自身不进入任务数据面;平台不提供组织或租户选择。 - 登录会话默认跨浏览器重启持续有效,不按空闲时间或绝对时长自动失效;用户退出、修改密码、账号停用或管理员强制撤销时由服务端立即撤销。 - 业务页面通过 REST 创建任务;Agent 返回结构化结果后,任务归属人在自己的任务上一次点击“确认并提交到 ERP 插件”,再通过 SSE 或轮询读取服务端状态。普通用户与组长的任务 API、SSE、附件和插件执行权限只覆盖分配给本人的人工任务与 AgentBus 任务;管理员是纯管理面身份,不能创建、查看、修改、领取、接收事件或提交任何业务任务。 - 手工与 AgentBus 的每个新任务都会按同一组织、同一 18 项业务路由固化解析策略及配置 revision;来源不能覆盖模式。其中两项名单 route 固定为 `program_only`,其余 16 项可配置 `ai / shadow / auto / program`。全消息中的唯一已登记指令可以确定 route;没有指令时,只有全部标签都属于唯一 route、至少两个不同标签且业务定位必填项完整的字段签名才可确定 route。未知、冲突或多 route 输入不猜测。后续补充轮次沿用原任务快照,设置变化只影响新任务和新会话。 diff --git a/control-plane/src/parser-orchestrator.ts b/control-plane/src/parser-orchestrator.ts index 5812dde..4fe4a47 100644 --- a/control-plane/src/parser-orchestrator.ts +++ b/control-plane/src/parser-orchestrator.ts @@ -73,7 +73,7 @@ export class ParserOrchestrator { // Unresolved/legacy traffic and tasks explicitly pinned to AI preserve the // original parser path. This is also the permanent affinity after an Auto - // fallback or the one-time administrator AI reparse. + // fallback or the legacy one-time task AI reparse. if (!routeId || configuredMode === 'ai' || affinity === 'ai') { const started = performance.now(); const aiResult = await this.aiParser.parse(this.aiInput(claim, signal)); diff --git a/control-plane/src/task-service.ts b/control-plane/src/task-service.ts index 400a9c8..05ac59c 100644 --- a/control-plane/src/task-service.ts +++ b/control-plane/src/task-service.ts @@ -5924,7 +5924,7 @@ export class TaskService { ? failure ? `解析失败【${failure.failure_stage}】:${failure.failure_message}` : '解析失败:系统解析未通过,任务已阻断。' - : '指令已拆解,等待管理员确认。'; + : '指令已拆解,等待任务归属人确认。'; const outcome = await withTransaction(this.config, async (client) => { const lookup = await client.query( 'SELECT * FROM tasks WHERE organization_id = $1 AND task_id = $2 FOR UPDATE', diff --git a/control-plane/test/control-plane.test.ts b/control-plane/test/control-plane.test.ts index 26264a5..61d3d71 100644 --- a/control-plane/test/control-plane.test.ts +++ b/control-plane/test/control-plane.test.ts @@ -1438,6 +1438,8 @@ test('operator page has a login gate and uses the durable task API', async () => assert.match(index, /确认并提交到 ERP 插件/); assert.match(app, /const MANUAL_HANDOFF_LABEL = '确认并提交到 ERP 插件'/); assert.match(app, /async function confirmAndSubmitToErpPlugin/); + assert.match(taskService, /指令已拆解,等待任务归属人确认/); + assert.doesNotMatch(taskService, /指令已拆解,等待管理员确认/); assert.doesNotMatch(app, /textContent = canStart \? '开始执行' : '确认执行'/); assert.match(app, /fetchWithTimeout\('\/api\/auth\/login'/); assert.match(app, /showAuthChecking\(\);[\s\S]*pingAi\(\)\.catch/); diff --git a/dist/ltjt-order-assistant-0.5.169.zip b/dist/ltjt-order-assistant-0.5.169.zip new file mode 100644 index 0000000..d52abf9 Binary files /dev/null and b/dist/ltjt-order-assistant-0.5.169.zip differ diff --git a/dist/release-manifest.json b/dist/release-manifest.json index 0b3f0c2..b202e57 100644 --- a/dist/release-manifest.json +++ b/dist/release-manifest.json @@ -2,7 +2,7 @@ "manifest_version": 1, "generated_on": "2026-09-07", "baselines": { - "chrome_extension": "0.5.168", + "chrome_extension": "0.5.169", "skills": "0.5.126", "business_instruction_docx": "0.5.126", "agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories" @@ -10,10 +10,10 @@ "artifacts": [ { "kind": "chrome_extension", - "version": "0.5.168", - "path": "dist/ltjt-order-assistant-0.5.168.zip", + "version": "0.5.169", + "path": "dist/ltjt-order-assistant-0.5.169.zip", "source": "chrome-extension/ltjt-order-assistant", - "sha256": "2432a882f2fbdcf28bfb6bb8a7fead55986297f86d4cf4ab8e12ea373c72518c" + "sha256": "00ad06a1640d36cfe7df8c9e52d677131793c70d493392b551b7ecbd965c854b" }, { "kind": "skill", diff --git a/mappings/lifecycle.mapping.json b/mappings/lifecycle.mapping.json index eb4cd25..d241bc3 100644 --- a/mappings/lifecycle.mapping.json +++ b/mappings/lifecycle.mapping.json @@ -1,7 +1,7 @@ { "contract_version": "ltjt-lifecycle-v2.9-roster-leader-contact-2026-08", "current_agent_parse_prompt_version": "ltjt-agent-prompt-v1.8-independent-headcount-categories", - "current_extension_version": "0.5.168", + "current_extension_version": "0.5.169", "historical_test_marker": "TEST-202609", "scope": "/System/Business/", "erp_session_keepalive": { @@ -114,7 +114,7 @@ ], "metadata_boundary": "session/task IDs, important summaries, confirmations and user communications stay in the platform envelope; they are not Agent operation data or ERP business fields", "uncertain_write": "requery_first_no_auto_retry", - "reconciliation": "administrator-triggered read-only fresh requery on the same operation/execution; never resubmit the ERP save action", + "reconciliation": "immutable-assignee-triggered read-only fresh requery on the same operation/execution; never resubmit the ERP save action", "shared_child_identity": "prefer the stable hidden oldtdid parent reference; only fall back to regular tid controls or the URL when oldtdid is absent, and always pair it with the exact child ddid", "completed_edit_dialog_cleanup": "after verified ERP evidence, run cleanup from the surviving top page (never from the frame that may navigate on save), require one exact route/reference candidate plus fresh identity proof; explicit test-context tasks additionally require TEST-202609/account/tid/ddid ownership, retry close at most three times, and verify exact iframe detachment", "forbidden_side_effects": [ diff --git a/tools/lifecycle-contract.test.mjs b/tools/lifecycle-contract.test.mjs index 27b3bcf..8430b40 100644 --- a/tools/lifecycle-contract.test.mjs +++ b/tools/lifecycle-contract.test.mjs @@ -1318,7 +1318,7 @@ test('passenger explicit server success is terminal without a post-save row requ assert.doesNotMatch(passengerBranch, /passengerRequery|verifyLifecycleOperation/); assert.doesNotMatch(background, /attemptAutomaticPassengerReconciliation/); assert.match(background, /名单已取得 ERP 明确成功响应,按业务规则确认录入成功/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.168'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.169'/); }); test('uncertain lifecycle writes can only converge through a read-only plugin requery', async () => { @@ -1345,6 +1345,9 @@ test('uncertain lifecycle writes can only converge through a read-only plugin re assert.doesNotMatch(readOnlyBody, /liveSubmitLifecycleOperation/); assert.match(background, /message\?\.type === 'LTJT_RECONCILE_TASK'/); assert.match(background, /resolvesReconciliation/); + assert.match(background, /等待任务归属账号人工只读核验/); + assert.match(background, /任务继续等待归属账号人工核验/); + assert.doesNotMatch(background, /等待管理员(?:只读)?核验/); assert.match(bridge, /message\.type === 'RECONCILE_TASK'/); assert.match(bridge, /type: 'LTJT_RECONCILE_TASK'/); assert.match(platform, /function canReconcileTask/); @@ -1525,7 +1528,7 @@ test('lifecycle execution keeps the MV3 worker alive until the durable task sett assert.match(background, /arrangement_resource_candidate_data_missing/); }); -test('extension 0.5.168 keeps reload dormant unless its durable execution state is fully idle', async () => { +test('extension 0.5.169 keeps reload dormant unless its durable execution state is fully idle', async () => { const [background, bridge] = await Promise.all([ readFile(new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), 'utf8'), readFile(new URL('../chrome-extension/ltjt-order-assistant/business-bridge.js', import.meta.url), 'utf8') @@ -1964,7 +1967,7 @@ test('delete guard distinguishes independent, shared child, and shared parent ro for (const operation of operations) assert.equal(plans.validateOperation(operation).ok, true, plans.validateOperation(operation).blockers.join('; ')); const mapping = JSON.parse(await readFile(new URL('../mappings/lifecycle.mapping.json', import.meta.url), 'utf8')); - assert.equal(mapping.current_extension_version, '0.5.168'); + assert.equal(mapping.current_extension_version, '0.5.169'); assert.equal( mapping.updates.order_update_independent.field_mapped_pending_live_validation['pax.child_no_bed'], 'ertrenshu' @@ -2348,10 +2351,10 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov assert.match(inpage, /`ys_danweiid\$\{index\}`, resolvedCustomerId/); assert.doesNotMatch(inpage, /product_customer_source_region|sourceRegionCheck|source_reference/); assert.doesNotMatch(teamBatchInpage, /product_customer_source_region|sourceRegionCheck/); - assert.equal(extensionManifest.version, '0.5.168'); - assert.match(inpage, /version: '0\.5\.168'/); - assert.match(teamBatchInpage, /version: '0\.5\.168'/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.168'/); + assert.equal(extensionManifest.version, '0.5.169'); + assert.match(inpage, /version: '0\.5\.169'/); + assert.match(teamBatchInpage, /version: '0\.5\.169'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.169'/); assert.match(inpage, /function strictIsoDate\(value\)/); assert.match(inpage, /const startDate = strictIsoDate\(controlCanonicalValue\(form, 'riqi0'\)\)/); assert.match(inpage, /const endDate = strictIsoDate\(controlCanonicalValue\(form, 'riqis0'\)\)/); diff --git a/tools/persist_extension_result_via_browser_session.mjs b/tools/persist_extension_result_via_browser_session.mjs index e1d0a0c..f02c9e9 100644 --- a/tools/persist_extension_result_via_browser_session.mjs +++ b/tools/persist_extension_result_via_browser_session.mjs @@ -91,7 +91,7 @@ const rawResult = evaluated.result?.value; 'X-CSRF-Token': csrfBody.csrf_token }, body: JSON.stringify({ - connection_id: `administrator-browser:${ORIGIN}`, + connection_id: `task-owner-browser:${ORIGIN}`, execution_id: result.execution_id, result })