Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 6 additions & 25 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Security

- Replaced production OIDC payload decoding with discovery, exact issuer
binding, S256 PKCE, nonce protection, JWKS-backed RS256 signature
verification, audience and authorized-party checks, bounded provider I/O,
verified-email enforcement, and single-use callback state. The local
provider now requires explicit `SCOPEWEAVE_DEV=1`.
- Made `SCOPEWEAVE_JWT_SECRET` mandatory at startup and rejected weak or
unexpanded placeholder values so production deployments fail closed.
- Neutralized audit-log CSV formulas even when executable prefixes are hidden
Expand All @@ -32,33 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added regression coverage that prevents array-valued passwords from being
coerced into valid credentials.
- Updated Hono runtime dependencies to patched supported releases.
- Sanitized Clearfolio submission, status, and artifact-link transport failures
so network details and downstream response text cannot reach browser or
diagnostic payloads; rejected unknown or whitespace-padded conversion states
and malformed, unsupported-scheme, or HTTPS-downgrade artifact links.
- Centralized session JWT verification and database-backed `token_version`
revocation across bearer middleware, calendar feeds, server-sent events, and
attachment-view URL transports.
- Made session-token minting fail closed unless the subject, token version, and
lifetime are bounded safe integers, and capped general session lifetime at
seven days so internal callers cannot mint excessive or numerically unsafe
credentials.
- Rejected signed session JWTs with a non-HS256/JWT header, non-object claims,
missing or invalid subject/expiry, or a missing, Boolean, fractional,
negative, unsafe, or otherwise invalid token-version claim before user lookup.
- Added cross-device regression coverage proving that `logout-all` rejects stale
tokens on bearer, calendar, SSE, and attachment-view transports while the
replacement token continues through the same authentication boundary.

### Changed

- Attachment-list status refresh now removes the per-row database lookup,
uses a configurable bounded worker pool with per-item abortable timeouts and
a request-wide latency budget, preserves stale status after downstream,
timeout, malformed-response, and persistence failures, excludes internal
conversion identifiers from responses, reports attempted, changed, failed,
skipped-data, and deferred-budget counters separately, and exposes fixed
low-cardinality timeout, lookup, validation, and persistence failure counters.
- 프로젝트 이름 입력 필드에 입력 예시(placeholder)를 추가하여 사용자 편의성을 개선했습니다.
- 데이터 테이블의 반복되는 액션 버튼에 컨텍스트 정보(작업명)를 포함한 명시적인 ARIA 레이블을 추가하고, 유효성 검사 에러를 폼 필드에 연결하여 접근성을 개선했습니다.
- `createGanttBarElement`, `renderGantt`, `buildWeekdayTimeline`에서 반복적으로 호출되던 `compareDateStrings`를 직접적인 문자열 비교 연산(`>=`, `<=`)으로 교체하여 O(N*D) 복잡도의 캐시 스레싱과 정규식 검사를 방지했습니다.
Expand All @@ -85,4 +66,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.0.1] - 2026-06-25
### 성능 개선 (Performance)
- 드래그 앤 드롭 동작 중 `dragover` 이벤트에서 발생하는 O(N) 작업 리스트 검색 성능 병목 문제를, O(1) 해시맵(Map) 기반의 캐싱 조회 로직으로 개선하여 큰 크기의 WBS 리스트에서의 버벅임 현상을 해결했습니다.
- 드래그 앤 드롭 동작 중 `dragover` 이벤트에서 발생하는 O(N) 작업 리스트 검색 성능 병목 문제를, O(1) 해시맵(Map) 기반의 캐싱 조회 로직으로 개선하여 큰 크기의 WBS 리스트에서의 버벅임 현상을 해결했습니다.
76 changes: 0 additions & 76 deletions docs/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,84 +41,8 @@ persists the database in the `scopeweave-data` volume.
| `ORCHESTRATOR_TOKEN` | with URL | orchestrator Bearer 토큰 (`CONTEXTUAL_ORCHESTRATOR_TOKEN`). |
| `CLEARFOLIO_URL` | for 산출물 viewer | Clearfolio 문서 뷰어 백엔드 주소. Unset → built-in mock (dev/test). |
| `CLEARFOLIO_HMAC_SECRET` | optional | Signs tenant-claim headers (`clearfolio.tenant-claims.hmac-secret`와 동일 값). |
| `SCOPEWEAVE_ATTACHMENT_STATUS_CONCURRENCY` | no (default 8, maximum 32) | Maximum concurrent Clearfolio status lookups during one attachment-list request. Invalid values fall back to 8; values above 32 are clamped. |
| `SCOPEWEAVE_ATTACHMENT_STATUS_TIMEOUT_MS` | no (default 3000, maximum 30000) | Hard caller-side timeout for each Clearfolio status lookup. The AbortSignal is also forwarded downstream. |
| `SCOPEWEAVE_ATTACHMENT_STATUS_BUDGET_MS` | no (default 5000, maximum 60000) | Wall-clock budget for the entire best-effort refresh pass. Work not started before the deadline is deferred to a later list request. |
| `SCOPEWEAVE_RATE_LIMIT_MAX` (+ `SCOPEWEAVE_RATE_LIMIT_WINDOW_MS`) | recommended | Per-IP fixed-window rate limiting (429 + Retry-After). Off when unset. |

## Attachment status refresh operations

The attachment-list API reads `job_id` in its initial project-scoped query and
refreshes only `PENDING` or `RUNNING` rows through a bounded worker pool. It
never performs one database lookup per row. A timeout, unsuccessful HTTP
response, malformed response body, invalid status value, or persistence failure
is isolated to that attachment: ScopeWeave preserves its previously stored
status and still returns the rest of the list. Internal Clearfolio job
identifiers are removed before JSON serialization.

The process metrics endpoint exposes cumulative counters for operational
monitoring:

- `attachmentStatusRefreshAttempted`
- `attachmentStatusRefreshChanged`
- `attachmentStatusRefreshFailed`
- `attachmentStatusRefreshSkipped`
- `attachmentStatusRefreshDeferred`
- `attachmentStatusRefreshTimeoutFailures`
- `attachmentStatusRefreshDownstreamLookupFailures`
- `attachmentStatusRefreshInvalidStatusFailures`
- `attachmentStatusRefreshPersistenceFailures`

`skipped` counts pending rows that cannot be refreshed because their persisted
Clearfolio job identifier is absent or blank. `deferred` counts valid work that
was not started before the request-wide latency budget expired. Keeping these
causes separate prevents malformed stored data from being mistaken for
insufficient concurrency or downstream latency.

The four failure-category counters are fixed, low-cardinality diagnostics whose
sum equals the aggregate `failed` delta for a refresh pass. They contain no job
identifier, URL, downstream response text, or raw exception. The Prometheus
representation uses corresponding `scopeweave_attachment_status_refresh_*`
names. Alert on a sustained increase in `failed`, use the category counters for
triage, investigate `skipped` as a data-quality or migration defect, and compare
`deferred` with list traffic before increasing concurrency or the request-wide
budget. Raise limits conservatively because every worker consumes a downstream
Clearfolio connection; horizontal ScopeWeave replicas multiply the aggregate
concurrency.

### Rollout and alerting

Roll this behavior out behind a canary replica before raising limits across the
fleet. Start with concurrency `2`, the default per-item timeout, and a budget no
longer than the attachment-list latency objective. Compare the canary with the
previous version using the same tenant and Clearfolio environment.

Derive rates from counter deltas over the same observation window:

```text
failure_ratio = failed_delta / max(attempted_delta, 1)
skipped_ratio = skipped_delta / max(attempted_delta + skipped_delta, 1)
deferred_ratio = deferred_delta / max(attempted_delta + deferred_delta, 1)
change_ratio = changed_delta / max(attempted_delta, 1)
```

A high `failure_ratio` indicates downstream, timeout, malformed-response, or
persistence errors and should block rollout. A non-zero `skipped_ratio` indicates
an attachment persistence or migration defect and should be investigated before
changing worker limits. A high `deferred_ratio` indicates that the request-wide
budget is protecting latency at the cost of freshness; first inspect Clearfolio
latency and attachment-list size before increasing worker count or budget. Track
attachment-list p50, p95, and p99 latency beside these ratios. Thresholds must be
derived from observed production baselines and an agreed service-level objective
rather than copied from development data.

Rollback is configuration-first: reduce concurrency and budget without changing
the persisted attachment statuses. If the application version must be rolled
back, the previous implementation can read the unchanged schema; no migration
is required by this feature. Never place Clearfolio job IDs, HMAC material,
request URLs containing credentials, or downstream response bodies in metrics,
logs, traces, or alert annotations.

## Data & scale path

- **Dev / single node**: `node:sqlite` on a persistent volume (this setup). Simple, no external DB.
Expand Down
132 changes: 0 additions & 132 deletions docs/doctoring/attachment-status-refresh.md

This file was deleted.

Loading
Loading