Files
portfolio-hub/docs/discovery/dcy-006_20260513_daemon-id-and-single-daemon-asset-assignment.md
T
genichin e6b6a8715b feat: implement daemon model with registry and single-asset assignment (BAT-010, REQ-023/028)
Core Implementation (BAT-010):
- Add daemon registry schema and CRUD operations (req-023)
- Implement single-daemon asset assignment constraint (one asset per daemon)
- Add daemon_id field to service_token for daemon identification
- Add daemon.py CLI module for daemon management commands
- Add 20260513_0016_daemon_model.py migration for daemon tables

API Changes:
- GET /v1/assets: include daemon_id in AssetResponse
- POST /v1/assets/{asset_id}/ledger/trades: require daemon token binding
- GET /v1/user_info: include daemon metadata
- Enhanced service-token rotate to preserve daemon bindings

CLI Commands:
- pfhub daemon register --name <name> --runtime-id <runtime-id>
- pfhub daemon list
- pfhub daemon get <daemon-id>
- pfhub daemon revoke <daemon-id>

Requirements (REQ-023, REQ-028):
- REQ-023: Daemon Registry and Service Token Daemon Binding (Interface, Approved)
  * AC-1: daemon CRUD operations
  * AC-2: service token daemon binding for POST /v1/assets/{asset_id}/ledger/trades
  * AC-3: single daemon per asset (exact-one assignment model)
- REQ-028: README.md Daemon Provisioning Runbook update (Documentation, Approved)

Documentation:
- Add dcy-006 Discovery for daemon-id and single-daemon asset assignment
- Update README.md with Daemon Provisioning Runbook section
- Add BAT-010 batch documentation with planning, implementation, verification
- Update rel-006 release document (daemon model implementation)
- Update data-model.md with daemon and daemon_asset_assignment tables
- Update interface-contract.md with daemon registry APIs
- Update runtime-flows.md with daemon lifecycle flows

Breaking Changes:
- REQ-005~009, REQ-011~012 status reverted to Approved due to revised contract
  * daemon_id field addition and exact-one asset assignment requirement
  * Existing Implemented evidence invalidated by contract revision
  * BAT-001/002/008 re-verification required

Testing:
- Add test_daemon_registry.py for daemon CRUD operations
- Add test_daemon_assignment.py for single-asset assignment constraints
- Update test_auth.py, test_cli.py, test_v1.py for daemon support
- Verify daemon token binding in trade endpoint authorization

Impact:
- Database: 2 new tables (daemons, daemon_asset_assignments)
- Migration: 20260513_0016 creates daemon model schema
- CLI: 4 new daemon subcommands
- API: daemon_id propagation through v1 endpoints
- Verification: BAT-001/002/008 re-verification gates next release
2026-05-13 23:07:24 +00:00

25 KiB

0. 문서 상태

이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.

  • 상태: confirmed
  • 문서 ID: dcy-006_20260513_daemon-id-and-single-daemon-asset-assignment
  • 이슈명: daemon_id 도입 및 1자산 1데몬 자산 배정 모델 정립
  • 작성 시각(KST): 2026-05-13 17:08
  • 마지막 갱신 시각(KST): 2026-05-13 20:30
  • 대체됨: 없음
  • 후속 Discovery 참조: 없음
  • 생성된 REQ 참조: REQ-023, REQ-028

1. 계획 상태 요약

현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.

  • 연계 문서 현황:
    • 관련 점수 파일: 미생성
    • 관련 TODO/메모: 없음
  • 해석:
    • dcy-002 계열의 v1 API와 service-token 모델은 owner_user_id와 runtime_id까지만 표현하고 있어, 동일 user 아래 여러 daemon이 자산을 나눠 맡는 운영 모델을 서버가 이해하지 못한다.
    • 이번 Discovery는 runtime_id를 런타임 식별자로 유지하면서 stable daemon_id와 exact-one asset assignment를 도입할지, 그리고 그 변화가 /v1/assets, /v1/user_info, POST /v1/assets/{asset_id}/ledger/trades, rotate, 운영 provenance에 미치는 범위를 정의한다.

2. 요구사항 판정 결과

이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.

  • 판정: 신규
  • 근거
    • 기존 dcy-001~005 중 stable daemon identity와 1개 자산 = 정확히 1개 데몬 서버 강제 모델을 다루는 Discovery는 없다.
    • 이번 변경은 이미 Implemented인 REQ-005, REQ-006, REQ-007, REQ-008, REQ-009, REQ-012의 Requirement와 Acceptance Criteria를 다시 써야 하는 구조 변경이어서 기존 Discovery의 미세 수정으로 처리할 수 없다.

판정이 완전 중복인 경우: 이하 섹션 작성을 중단하고 # 9. 파일 처리 결과에 중복 판정 사유와 참조 문서 경로를 기록한 뒤 문서를 닫는다. REQ 초안 작성으로 넘기지 않는다.

3. 문제점의 요약

문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.

  • 현재 상태
    • GET /v1/assets는 현재 service-token 소유 user의 portfolio만 반환하며, daemon assignment 차원을 전혀 갖지 않는다.
    • runtime_id는 service-token 발급 시 생성되어 /v1/user_info로 반환되지만 rotate 시 다시 바뀌는 런타임 식별자라 stable asset assignment key로 쓰기 어렵고, /v1/user_info에는 아직 daemon_id가 포함되지 않는다.
    • 현재 스키마와 도메인 모델에는 daemons 테이블, auth_tokens.daemon_id, portfolios.managed_by_daemon_id가 없다.
    • 태그와 owner scope는 존재하지만 1개 자산은 정확히 1개 데몬만 담당을 서버에서 강제하는 모델이나 API 계약은 없다.
    • POST /v1/assets/{asset_id}/ledger/trades는 유효한 service-token 인증과 asset 존재성 기준으로 동작하며, "해당 asset이 이 daemon에 배정됐는가"는 검증하지 않는다.
  • 기대 상태
    • service-token은 runtime_id와 별도로 stable daemon_id에 바인딩된다.
    • daemon create/update는 별도 daemon registry 관리 경로에서 수행되고, service-token issue/rotate는 existing daemon reference만 받아 binding한다.
    • 각 asset은 동일 owner scope 안에서 정확히 1개의 daemon에만 배정되고, /v1/assets와 ledger write는 이 배정 규칙을 서버에서 강제한다.
    • GET /v1/user_info는 현재 인증 service-token에 기록된 daemon_id와 runtime 세대 식별자인 runtime_id를 함께 반환하며, 전환 구간의 NULL backfill token은 daemon_id = null을 진단 정보로 노출한다.
    • rotate나 runtime 재기동 이후에도 daemon_id는 유지되고 runtime_id만 갱신되어 운영 provenance와 runtime identity가 분리된다.
  • 이해관계자
    • trex-basic 데몬 운영자
    • portfolio-hub repository-maintainers
    • release approver / production operator
    • user ownership 및 asset assignment policy 승인자
  • 제약사항
    • service-token bearer auth와 기존 read/trade-write/admin 권한 모델은 유지한다.
    • 1개 자산 = 정확히 1개 데몬 규칙을 many-to-many 없이 모델링한다.
    • 신규 migration과 schema bootstrap은 기존 Alembic chain과 IF NOT EXISTS 정책을 깨지 않아야 한다.

주요 사용자 시나리오

사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.

  • 동일 user가 daemon-a, daemon-b 두 개를 운영할 때, daemon-a용 service-token으로 /v1/assets를 호출하면 daemon-a에 배정된 asset만 반환되고 daemon-b의 asset은 반환되지 않는다.
  • daemon-b가 daemon-a에 배정된 asset_id로 POST /v1/assets/{asset_id}/ledger/trades를 호출하면 403 Forbidden으로 거부되고, 잘못된 ledger row는 생성되지 않는다.
  • 운영자가 daemon-a용 service-token을 rotate할 때 runtime_id는 새 값으로 갱신되지만 daemon_id와 asset assignment는 유지되어, daemon 재배정 없이 provenance만 이어서 확인할 수 있다.

4. 이번에 정의할 변경

이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.

  • stable daemon identity 모델 추가: daemons registry, 별도 daemon create/update 관리 경로, service-token daemon_id binding, runtime_id와 daemon_id의 역할 분리
  • exact-one asset assignment 모델 추가: portfolios에 daemon assignment를 저장하고 daemon-scoped /v1/assets 조회와 ledger authorization로 1자산 1데몬 규칙을 강제
  • service-token issuance/rotate/provenance와 baseline 문서 갱신: daemon binding, 기존 asset/token의 NULL backfill, /v1/user_info와 CLI의 daemon_id 노출, 403 mismatch contract를 운영 절차와 함께 재정의

영향 범위

변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.

  • 코드 영향:
    • migrations/versions/: daemons 테이블, auth_tokens.daemon_id, portfolios.managed_by_daemon_id, 관련 FK/check/backfill migration 추가
    • app/domain/models.py, app/repositories/postgres.py, app/repositories/portfolio_repository.py: daemon model, token binding, asset assignment, rotate invariants 반영
    • app/services/auth_service.py, app/api/auth_routes.py, app/cli/commands/service_tokens.py: service-token issue/list/rotate에 daemon binding 및 provenance 반영
    • app/api/v1_assets.py, app/api/v1_user_info.py, app/api/v1_ledger.py: daemon-scoped read/write와 diagnostics contract 반영
  • 문서 영향:
    • docs/discovery/dcy-002_20260502_trex-basic-consumer-api-contract.md: 후속 Discovery 참조 및 runtime_id 역할 재정렬 필요
    • docs/srs/Interface/req-005_service-token-runtime-id-issuance.md, req-006_v1-assets-endpoint.md, req-007_v1-user-info-endpoint.md, req-008_v1-ledger-trades-endpoint.md, req-012_service-token-rotate-cli.md: change-req 대상
    • docs/srs/Migration/req-009_v1-api-db-schema-migration.md, docs/srs/Documentation/req-011_baseline-docs-update-for-trex-basic-contract.md: change-req 대상
    • docs/interface-contract.md, docs/data-model.md, docs/runtime-flows.md, README.md 운영 provenance 문서: daemon assignment 반영 필요
  • 운영 영향:
    • daemon create/update는 별도 관리 경로에서 먼저 수행하고, service-token issue/rotate는 existing daemon 선택 또는 daemon_id 입력으로만 binding한다.
    • 기존 asset과 token은 초기 migration에서 daemon 필드를 NULL로 backfill하며, production operator가 명시적 reassignment inventory와 전환 절차를 준비하고 release approver 승인 이후에만 daemon-scoped enforcement를 켠다.
    • rotate 후 runtime_id 재조회와 daemon_id 불변성 확인을 운영 support path에 포함해야 한다.
    • daemon-scoped enforcement enablement gate는 DATA_EXISTING_DEPLOYMENT_DAEMON_MAP 완료, active service-token/asset의 explicit reassignment 또는 제외 처리 완료, zero-active-NULL/zero-mismatch dry-run, smoke 검증 통과를 required evidence로 삼는다.

5. 요구사항 목록

실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.

기능 요구사항

  • FR-1: service-token은 steady state에서 runtime_id와 별도로 stable daemon_id에 정확히 1:1로 바인딩되어야 한다. daemon provisioning은 별도 daemon create/update 관리 경로에서 수행되며, issue/rotate는 existing daemon만 참조하고 unknown daemon 자동 생성/업서트를 허용하지 않는다. daemon_id는 rotate 이후에도 유지되며, runtime_id는 런타임 식별자로서 갱신될 수 있어야 한다. 기존 token backfill은 daemon_id = NULL로 시작할 수 있고, 이 상태의 token은 daemon-scoped API에서 fail-closed로 취급한다.
  • FR-2: 각 asset(portfolio)은 steady state에서 동일 owner scope 안에 정확히 1개의 daemon에 배정되어야 한다. 스키마와 migration은 이 exact-one assignment를 DB 레벨에서 표현하고 강제해야 하며, 기존 asset backfill은 managed_by_daemon_id = NULL로 시작할 수 있고 이 상태의 asset은 daemon-assigned state로 간주하지 않는다.
  • FR-3: GET /v1/assets는 service-token 소유 user의 전체 asset이 아니라, 인증된 token에 바인딩된 daemon에 배정된 asset만 반환해야 한다.
  • FR-4: POST /v1/assets/{asset_id}/ledger/trades는 인증된 daemon에 배정된 asset에 대해서만 성공해야 하며, daemon assignment mismatch 또는 미배정 asset에는 403 Forbidden으로 응답하고 ledger row를 생성하지 않아야 한다.
  • FR-5: GET /v1/user_info는 runtime_id와 함께 현재 인증 service-token의 daemon_id를 반환해야 하며, backfill로 daemon_id = NULL인 legacy token에는 그 NULL 값을 진단용으로 노출해야 한다. pfhub service-token issue/list/rotate 출력은 모두 daemon_id 필드를 포함해야 하며, POST /auth/service-tokens와 CLI issue/rotate는 기존 daemon registry에 존재하는 daemon만 바인딩 대상으로 받아야 한다. 운영 provenance 절차는 runtime_id와 daemon_id의 역할 차이를 명확히 드러내야 한다.
  • FR-6: baseline 문서와 운영 runbook은 daemon provisioning/binding, asset assignment, rotate invariants, 기존 데이터 backfill 절차를 반영해야 한다.

비기능 요구사항

성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.

  • NFR-1: runtime_id는 runtime identity, daemon_id는 stable logical identity로 역할이 분리되어야 하며, 어떤 API나 운영 절차도 runtime_id를 asset assignment key로 재사용하면 안 된다.
  • NFR-2: DB는 post-cutover steady state에서 service-token -> daemon, asset -> daemon 관계의 same-user consistency와 exact-one assignment를 FK/check/NOT NULL 제약으로 보장해야 한다. 전환 구간에서는 auth_tokens.daemon_id, portfolios.managed_by_daemon_id의 NULL backfill을 허용하되, explicit reassignment와 검증을 거쳐 exact-one assignment 상태로 수렴해야 하며, 누락 또는 mismatch 상황은 fail-open이 아닌 fail-closed로 처리해야 한다.
  • NFR-3: migration과 schema bootstrap은 기존 Alembic revision chain 및 IF NOT EXISTS 정책을 준수해야 하며, backfill이 완료되지 않은 상태에서 daemon-scoped enforcement가 부분 적용되지 않도록 해야 한다.

범위 경계

이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.

  • In Scope
    • stable daemon_id 모델과 service-token binding
    • exact-one asset assignment 및 daemon-scoped /v1/assets / ledger authorization
    • service-token rotate/list/issue/provenance의 runtime_id/daemon_id 역할 재정의
    • 필요한 migration, backfill 정책, baseline 문서 및 운영 runbook 반영
  • Out of Scope
    • trex-basic 측 consumer 코드 변경 자체
    • runtime heartbeat, leader election, lease/lock 같은 distributed runtime control
    • 1자산 N데몬, 예약 배정, 시간대별 assignment 같은 many-to-many 또는 temporal assignment 모델
    • 외부 사용자를 위한 daemon fleet 관리 UI 또는 공개 운영 포털 추가

6. 리스크/가정 목록

불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.

리스크

  • R-1 (High): 기존 asset과 token을 NULL로 backfill한 뒤 explicit daemon assignment가 늦어지면 기존 daemon이 /v1/assets와 ledger write에서 연쇄적으로 403을 맞아 운영 중단이 발생할 수 있다.
    • 완화 방안: production operator가 현재 배포 환경의 user -> daemon -> asset inventory와 explicit reassignment 계획을 준비하고, portfolio-hub repository-maintainers가 dry-run audit 결과를 검토한 뒤, release approver 승인 이후에만 daemon-scoped enforcement를 켠다.
  • R-2 (High): runtime_id와 daemon_id의 의미가 문서/코드/운영 절차마다 다르게 해석되면 rotate 이후 provenance와 asset assignment가 다시 흔들릴 수 있다.
    • 완화 방안: portfolio-hub repository-maintainers가 REQ와 테스트에서 "rotate는 runtime_id를 갱신하지만 daemon_id는 유지"를 불변식으로 명시하고, issue/list/rotate/user_info 출력 필드 정의를 함께 정렬한다.
  • R-3 (Medium): daemon-scoped enforcement를 켠 뒤에도 미배정 asset이나 daemon-less service-token이 남아 있으면 /v1/assets 또는 ledger write가 예고 없이 깨질 수 있다.
    • 완화 방안: production operator가 enforcement 이전 audit/report와 smoke 검증을 수행하고, release approver가 rollback approver를 겸해 on/off 판단을 승인한다.

가정

아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.

  • A-1: 동일 user가 여러 daemon을 가질 수 있지만, 각 daemon은 정확히 1명의 owner user에 속한다.
  • A-2: runtime_id는 per-token runtime identity로 유지되며 issue/rotate 시 갱신될 수 있다.
  • A-3: service-token bearer auth와 기존 read/trade-write/admin 권한 모델은 유지하고, daemon assignment는 그 위에 추가되는 authorization 축이다.
  • A-4: 1개 자산 = 정확히 1개 데몬 규칙은 태그나 외부 컨벤션이 아니라 DB-backed 서버 모델로 강제한다.

오픈 질문

답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.

  • 현재 Open 상태 OQ는 없다. 기존 OQ-1~OQ-4의 결정 사항은 본문과 # 10. 사용자 결정 필요 항목 요약에 반영했다.
  • OQ-4: daemon-scoped enforcement enablement gate — NULL backfill 상태의 daemon-scoped enforcement는 다음 조건이 모두 충족될 때만 활성화한다: DATA_EXISTING_DEPLOYMENT_DAEMON_MAP가 활성 user/service-token/asset 전체를 커버하고, active service-token은 모두 valid daemon_id에 바인딩되거나 명시적으로 revoke/disable되며, active asset은 모두 정확히 1개 daemon에 재배정되거나 명시적으로 전환 대상에서 제외되고, dry-run audit에서 zero-active-NULL/zero-mismatch가 확인되며, smoke 검증이 통과해야 한다.
    • 상태: Answered
    • 처리 방안: production operator가 inventory/reassignment/smoke evidence를 준비하고, portfolio-hub repository-maintainers가 dry-run audit과 contract test evidence를 검토하며, release approver가 enforcement on/off와 rollback approver를 겸해 최종 승인한다.
    • 종료 조건: required evidence set, owner, approver가 운영 runbook과 후속 REQ Acceptance Criteria에 반영되면 유지 결정으로 닫는다.

오픈 질문 처리 기준

  • Open: 아직 답이 없고 다음 단계 진행에 영향이 있는 상태다. 문서에 유지한다.
  • Answered: 답이 확정된 상태다. 관련 본문/요구사항에 반영한 뒤 오픈 질문 목록에서는 제거하거나 resolved 기록으로 이동한다.
  • Deferred: 지금 단계에서 결정하지 않고 다음 단계 또는 후속 이슈로 넘기는 상태다. 넘길 대상과 이유를 반드시 적는다.
  • Dropped: 더 이상 유효하지 않은 질문이다. 삭제 사유를 짧게 남기고 목록에서 제거한다.
  • 처리 원칙 1: 질문만 남기지 말고 반드시 상태, 처리 방안, 종료 조건을 함께 적는다.
  • 처리 원칙 2: 답이 나온 질문은 본문 반영 없이 단순 삭제하지 않는다. 반영 위치를 먼저 갱신한다.
  • 처리 원칙 3: High 영향 질문은 Deferred 처리 후 처리 방안에 REQ 인계 추적 방식을 명시한다.

7. 초기 성공 기준

이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.

  • S-1: 동일 user가 daemon-a, daemon-b를 운영할 때, 각 daemon의 service-token으로 호출한 GET /v1/assets는 해당 daemon에 배정된 asset만 반환한다.
  • S-2: daemon-a에 배정된 asset에 대해 daemon-b가 POST /v1/assets/{asset_id}/ledger/trades를 호출하면 403 Forbidden으로 거부되고 DB row가 생성되지 않으며, daemon-a 호출만 성공한다.
  • S-3: GET /v1/user_info와 pfhub service-token issue/list/rotate는 daemon_id를 노출하고, service-token rotate 이후 runtime_id는 변경되지만 daemon_id binding은 유지된다.
  • S-4: daemon create/update는 별도 registry 관리 경로에서만 수행되고, POST /auth/service-tokens와 CLI issue/rotate는 존재하지 않는 daemon 입력을 명시적으로 거부하며 자동 생성/업서트를 하지 않는다.
  • S-5: daemon-scoped enforcement는 inventory 완료, active token/asset reassignment 또는 제외 처리 완료, zero-active-NULL/zero-mismatch dry-run, smoke 검증 통과, release approver 승인 이후에만 활성화된다.
  • S-6: baseline 문서와 운영 runbook이 daemon provisioning, asset assignment, enforcement enablement gate, rotate invariants, backfill 절차를 반영하고 더 이상 runtime_id를 asset assignment key처럼 설명하지 않는다.

측정 방식 및 데이터 출처

각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.

  • S-1 측정 방식: pytest로 동일 user 아래 2개 daemon과 2개 asset을 구성해 daemon-scoped /v1/assets 응답을 검증 / 데이터 출처: tests/test_v1.py 또는 신규 tests/test_daemon_assignment.py
  • S-2 측정 방식: pytest로 daemon mismatch ledger write를 호출해 403 응답과 DB row count 무변경을 검증 / 데이터 출처: tests/test_v1.py 또는 신규 tests/test_daemon_assignment.py
  • S-3 측정 방식: targeted auth/CLI/API 테스트로 rotate 전후 runtime_id/daemon_id invariants와 daemon_id diagnostics 노출을 검증 / 데이터 출처: tests/test_auth.py, tests/test_cli.py, tests/test_v1.py
  • S-4 측정 방식: targeted auth/CLI/API 테스트로 unknown daemon binding 요청이 명시적으로 실패하고 daemon auto-create/upsert가 발생하지 않음을 검증 / 데이터 출처: tests/test_auth.py, tests/test_cli.py, tests/test_v1.py 또는 신규 tests/test_daemon_registry.py
  • S-5 측정 방식: cutover checklist와 dry-run/smoke evidence로 active token/asset reassignment 완료, zero-active-NULL/zero-mismatch, release approver 승인 여부를 확인 / 데이터 출처: 운영 cutover checklist, audit report, smoke test log
  • S-6 측정 방식: baseline 문서와 운영 runbook에 daemon assignment, enforcement enablement gate, backfill 절차가 반영됐는지 코드 리뷰로 확인 / 데이터 출처: docs/interface-contract.md, docs/data-model.md, docs/runtime-flows.md, README.md

8. REQ로 넘기기 전 확인 체크

REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.

  • 범위(In Scope/Out of Scope) 확정
    • 기준: daemon provisioning path를 포함한 주요 정책 결정이 범위와 함께 본문 및 section 10에 반영되어야 함
  • 성공 지표의 측정 방식/데이터 출처 확정
    • 기준: S-1~S-6이 pytest, 운영 evidence, 또는 문서 리뷰 evidence로 추적 가능한 수준으로 정리되어야 함
  • High 영향 리스크 우선순위 및 해소 책임자 지정
    • 기준: R-1 backfill/reassignment owner는 production operator, R-2 runtime/daemon provenance owner는 portfolio-hub repository-maintainers, rollback approver는 release approver로 지정되어야 함
  • 모든 오픈 질문(OQ) Open 상태 없음 확인
    • 기준: OQ 목록에 Open 상태 항목이 0개이거나, 잔여 항목 전부 Deferred 처리 완료
  • Freeze 확정 담당자(CONFIRMED_BY) 지정
    • 기준: confirm-discovery 게이트에서 범위 승인자와 후속 REQ drafting owner가 지정되어야 함

9. 파일 처리 결과

이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.

  • 처리 결과: 생성 후 갱신
  • 생성 경로: docs/discovery/dcy-006_20260513_daemon-id-and-single-daemon-asset-assignment.md
  • 참조 문서:
    • docs/discovery/dcy-002_20260502_trex-basic-consumer-api-contract.md
    • docs/discovery/dcy-005_20260511_production-admin-bootstrap-and-operator-access.md
    • docs/srs/Interface/req-005_service-token-runtime-id-issuance.md
    • docs/srs/Interface/req-006_v1-assets-endpoint.md
    • docs/srs/Interface/req-007_v1-user-info-endpoint.md
    • docs/srs/Interface/req-008_v1-ledger-trades-endpoint.md
    • docs/srs/Migration/req-009_v1-api-db-schema-migration.md
    • docs/srs/Interface/req-012_service-token-rotate-cli.md

10. 사용자 결정 필요 항목 요약

사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.

DECIDE

  • 없음

CONFIRM

  • 없음 (Confirmed By: Justin — 2026-05-13)

DATA

  • baseline 반영 완료
    • DATA_EXISTING_DEPLOYMENT_DAEMON_MAP: canonical acceptance environment는 production이고, staging은 optional preflight, local/local-test는 cutover evidence 대상에서 제외한다. 현재 저장소 기준으로 확인되는 external consumer daemon lineage는 trex-basic 1종이며, production operator는 실제 cutover checklist와 release evidence에 환경별 row를 (environment, username 또는 user_id, daemon_slug, daemon_display_name, service_token_name, token_prefix, permission, asset_ids, state[active|excluded|revoked]) 형식으로 기록한다. raw secret 값은 저장소에 남기지 않고, production canonical secret material location은 host-side EnvironmentFile=/opt/portfoliohub/.env 운영 경로를 따른다.
    • DATA_DAEMON_NAMING_RULES: daemon_display_name은 trim된 non-empty human-readable label로 두고, daemon_slug는 owner user 내에서 unique한 stable identifier로 관리한다. 현재 consumer lineage 기준 권장 slug prefix는 trex-basic이며, slug 표기는 lowercase kebab-case를 사용한다. canonical operator 표기와 cutover evidence 표기는 <username>/<daemon_slug>로 통일하고, provenance 추적에는 daemon_slug, service_token_name, token_prefix를 함께 기록한다.

11. Discovery Freeze

REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.

섹션 참조

Freeze 플래그

  • Handoff Decision: 승인
  • Handoff Rationale: 현재 저장소를 재확인한 결과 /v1/assets는 아직 owner-user scope만 사용하고, /v1/user_info는 runtime_id만 반환하며, POST /v1/assets/{asset_id}/ledger/trades는 daemon assignment 검증이 없고, service-token CLI도 daemon binding/diagnostics를 아직 다루지 않는다. 문서의 현재 상태 서술, FR/NFR, 성공 기준, section 10 DATA baseline은 이 현실과 일치하며, Open OQ와 C 유형 플레이스홀더는 0개다. cutover checklist row와 smoke evidence는 release 단계의 운영 검증 산출물로 남기고, REQ drafting handoff 자체를 막는 항목으로 두지 않는다.
  • Ready for REQ Drafting: true
  • Confirmed By: Justin
  • Confirmed At (KST): 2026-05-13 19:17