From 49e61ef3ab31c1a45a7b0892e5854b9db49b0004 Mon Sep 17 00:00:00 2001 From: toki Date: Tue, 16 Jun 2026 10:32:57 +0900 Subject: [PATCH] update workspace operations rules and add new skills/templates --- .clinerules | 1 + .cursorrules | 1 + .workspace-ops/README.md | 3 +- .workspace-ops/docs/build-jenkins-oto.md | 141 ++++++++++++++ .workspace-ops/docs/environments.md | 1 + .workspace-ops/docs/ports.md | 2 + .workspace-ops/docs/remote-runners.md | 5 + .../docs/remote-test-environments.md | 2 + .workspace-ops/docs/secrets-sops.md | 58 ++++++ .workspace-ops/rules/common/rules.md | 4 + .workspace-ops/rules/domains/secrets/rules.md | 36 ++++ .workspace-ops/rules/project/rules.md | 12 ++ .../skills/build-management/SKILL.md | 57 ++++++ .../SKILL.md | 145 +++++++++++++++ .../scripts/collect.sh | 175 ++++++++++++++++++ .workspace-ops/skills/router.md | 19 ++ .../skills/secrets-management/SKILL.md | 56 ++++++ .../weekly-subproject-work-summary/SKILL.md | 118 ++++++++++-- .../scripts/collect.sh | 8 + .workspace-ops/templates/build-jenkins-oto.md | 38 ++++ .workspace-ops/templates/entry-file.md | 1 + .workspace-ops/templates/secrets-sops.md | 37 ++++ AGENTS.md | 1 + CLAUDE.md | 1 + GEMINI.md | 1 + 25 files changed, 907 insertions(+), 16 deletions(-) create mode 100644 .workspace-ops/docs/build-jenkins-oto.md create mode 100644 .workspace-ops/docs/secrets-sops.md create mode 100644 .workspace-ops/rules/domains/secrets/rules.md create mode 100644 .workspace-ops/skills/build-management/SKILL.md create mode 100644 .workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md create mode 100755 .workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh create mode 100644 .workspace-ops/skills/router.md create mode 100644 .workspace-ops/skills/secrets-management/SKILL.md create mode 100644 .workspace-ops/templates/build-jenkins-oto.md create mode 100644 .workspace-ops/templates/secrets-sops.md diff --git a/.clinerules b/.clinerules index e515591..95ce1b0 100644 --- a/.clinerules +++ b/.clinerules @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다. diff --git a/.cursorrules b/.cursorrules index e515591..95ce1b0 100644 --- a/.cursorrules +++ b/.cursorrules @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다. diff --git a/.workspace-ops/README.md b/.workspace-ops/README.md index 50172fb..ed945b3 100644 --- a/.workspace-ops/README.md +++ b/.workspace-ops/README.md @@ -9,7 +9,7 @@ - `skills/`: 일간/주간 분석, 주간 작업 요약, 구현 전 점검 skill - `shared/`: skill들이 공유하는 평가 기준, 출력 형식, 대상 탐색 문서와 스크립트 - `config/`: workspace 기준 설정 파일 -- `docs/`: 포트, 환경, 원격 runner 같은 운영 문서 +- `docs/`: 포트, 환경, 원격 runner, SOPS 시크릿, Jenkins/OTO 빌드 같은 운영 문서 - `roadmap-sync/`: cross-repo roadmap sync lock 자료 - `scripts/`: workspace 운영 보조 스크립트 @@ -18,4 +18,5 @@ - root의 `AGENTS.md`, `GEMINI.md`, `CLAUDE.md`, `.cursorrules`, `.clinerules`는 호환용 진입 파일이다. - 실제 규칙 원본은 `.workspace-ops/rules/common/rules.md`에 둔다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 기준으로 한다. +- workspace 공통 관리 작업은 `.workspace-ops/skills/router.md`에서 해당 domain rule과 skill을 고른다. - `.workspace-ops/**`는 하위 프로젝트 분석 대상에서 제외한다. diff --git a/.workspace-ops/docs/build-jenkins-oto.md b/.workspace-ops/docs/build-jenkins-oto.md new file mode 100644 index 0000000..09caa07 --- /dev/null +++ b/.workspace-ops/docs/build-jenkins-oto.md @@ -0,0 +1,141 @@ +# Workspace Build Management: Jenkins And OTO + +This guide defines workspace-level build guidance for Jenkins and OTO-backed +build/deploy flows. It does not replace project-owned build commands. + +## Principles + +- Project-local commands are the source of truth for build behavior. +- Jenkins may orchestrate shared or scheduled builds. +- OTO may act as the build/deploy domain agent when a project explicitly uses + OTO for that flow. +- Credentials used by builds follow `.workspace-ops/docs/secrets-sops.md`. +- Evidence should be reproducible without exposing private job URLs, tokens, or + host secrets. + +## Responsibility Split + +| Area | Owner | +|---|---| +| Unit test/build commands | project repository | +| Shared scheduled execution | Jenkins, when configured | +| Build/deploy domain agent behavior | OTO, when configured | +| Remote runner environment | workspace inventory and project `agent-test/local` | +| Secret injection | project runtime plus SOPS/secret guide | +| Artifact naming and retention | project or Jenkins job, documented in project guide | +| Evidence logs | project task/review docs or workspace summary, without secrets | + +## Jenkins Remote API With SOPS + +Jenkins automation credentials are project-owned secrets. Store only encrypted +material in the project repository, and keep decryption identities on the +remote runner or operator machine. + +Recommended encrypted keys: + +| Key | Purpose | +|---|---| +| `jenkins_url` | Base URL used by the automation runtime | +| `jenkins_username` | Jenkins user used for API calls | +| `jenkins_api_token` | Jenkins API token with the minimum job permissions | + +Recommended project layout: + +| Item | Location | +|---|---| +| SOPS policy | project root `.sops.yaml` | +| Encrypted CI secret | project-owned `secrets/*.sops.json` or existing project convention | +| Local age/GPG identity | ignored runner-local path, such as `$HOME/.config/sops/age/-ci-key.txt` | + +API validation must not print decrypted values. Use a temporary file, load only +the required keys, call a low-impact endpoint, and remove the temporary output. + +```bash +export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/-ci-key.txt" + +secret_json="$(mktemp)" +secret_env="$(mktemp)" +trap 'rm -f "$secret_json" "$secret_env"' EXIT + +sops -d secrets/.ci.sops.json > "$secret_json" + +python3 - "$secret_json" > "$secret_env" <<'PY' +import json +import shlex +import sys + +payload = json.load(open(sys.argv[1])) +mapping = { + "jenkins_url": "JENKINS_URL", + "jenkins_username": "JENKINS_USERNAME", + "jenkins_api_token": "JENKINS_API_TOKEN", +} +for source, target in mapping.items(): + print(f"{target}={shlex.quote(payload[source])}") +PY + +. "$secret_env" + +curl -sS --fail \ + --user "$JENKINS_USERNAME:$JENKINS_API_TOKEN" \ + "$JENKINS_URL/whoAmI/api/json" >/dev/null +``` + +For Jenkins POST calls, fetch a crumb when CSRF protection is enabled and pass +it as a header. Keep the crumb in a shell variable; do not echo it to logs. + +```bash +crumb_header="$( + curl -sS --fail \ + --user "$JENKINS_USERNAME:$JENKINS_API_TOKEN" \ + "$JENKINS_URL/crumbIssuer/api/json" | + python3 -c 'import json, sys; p=json.load(sys.stdin); print(p["crumbRequestField"] + ":" + p["crumb"])' +)" + +curl -sS --fail -X POST \ + --user "$JENKINS_USERNAME:$JENKINS_API_TOKEN" \ + -H "$crumb_header" \ + -H "Content-Type: application/xml" \ + --data-binary @job-config.xml \ + "$JENKINS_URL/createItem?name=" +``` + +Minimum Jenkins permissions depend on the operation. A thin job setup usually +needs `Job/Create`, `Job/Configure`, `Job/Build`, and `Job/Read`. Artifact +download validation needs `Job/Read` and artifact access for the selected job. + +Tracked docs may record key names, encrypted file paths, job naming rules, and +validation command classes. They must not record raw token values, decrypted +payloads, private account values, or tokenized artifact URLs. + +## Project Guide Should Record + +- project build commands, such as `bin/test`, `bin/lint`, `bin/build`, or + `make test` +- Jenkins job class or naming rule if Jenkins is used +- OTO role if OTO is used +- artifact output path or naming convention +- evidence location and minimum result fields +- credential injection boundary, linked to the SOPS guide +- remote runner requirements when local validation is insufficient + +## Evidence Fields + +Build evidence should include: + +- command or Jenkins/OTO job class +- project and branch/ref +- environment class, such as local, remote runner, Jenkins, or OTO +- result +- artifact path or identifier class when applicable +- follow-up action when failed + +Do not include raw credential values or private tokenized URLs. + +## Safety Checklist + +- [ ] Project-local command is documented. +- [ ] Jenkins/OTO responsibility does not override project source of truth. +- [ ] Artifact and evidence paths are documented. +- [ ] Build credentials are referenced through the SOPS/secret guide. +- [ ] Remote runner assumptions match `.workspace-ops/docs/remote-test-environments.md`. diff --git a/.workspace-ops/docs/environments.md b/.workspace-ops/docs/environments.md index b9c068c..083407e 100644 --- a/.workspace-ops/docs/environments.md +++ b/.workspace-ops/docs/environments.md @@ -18,6 +18,7 @@ | `iop` | Docker compose 기반 Control Plane, Edge, Node, Client, PostgreSQL, Redis. work container 안 Docker-in-Docker는 피한다. dev profile은 local/test 조건을 유지하되 `.env.dev.example`으로 host publish 포트만 분리한다. | `ssh toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev` | workspace 기준 프로젝트. local/test frontend `13000`, backend `18000`, artifact/model `18080/18081`, wire `19080/19081/19090`, metrics `19092`, DB/cache `15400/16300`. dev frontend `13001`, backend `18001`, wire `19001/19002/19003`, DB/cache `15401/16301`, optional artifact/model `18082/18083`, metrics `19101`. | | `nexo` | Mattermost core, webapp, push-proxy, Flutter test host, upstream dev compose | `ssh toki@toki-labs.com`, repo `~/agent-work/nexo`, compose `~/docker/agent-service/nexo/compose` | core `18065`, push-proxy `18066`은 compatibility baseline. upstream dev compose 포트는 nexo-owned runtime 포트와 분리한다. | | `nomadcode` | Core local default `8080`, Docker compose DB/Redis, Flutter client, code-server preview | Android runner `$HOME/agent-work/nomadcode`, sibling `../nexo/packages/messaging_flutter`, `../proto-socket/dart` | frontend 후보 `13010`, backend 후보 `18010`, DB/cache `15410/16310`. Plane, Mattermost, Jira, IOP Edge endpoint는 secret 없이 책임 경계만 기록한다. | +| `gito` | Core local default `8080`, Go control plane/worker/shell, Flutter client, optional Postgres/Redis/proto-socket runner smoke. 기본 local 테스트 evidence는 standard remote runner 기준 | `ssh toki@toki-labs.com`, `$HOME/agent-work/gito` | frontend `13060`, backend/Core HTTP `18060`, optional wire/agent transport `19060`, DB/cache `15460/16360`. Core 내부 listen `8080`은 유지하되 shared runner 검증은 gito-owned host slot을 사용한다. | | `oto` | 기본 local 테스트 evidence는 remote runner 기준. OTO Core product fallback `127.0.0.1:8080`, runner typed-command tests, Flutter client는 compatibility 경로로 유지 | `ssh toki@toki-labs.com`, `/Users/toki/agent-work/oto` | frontend `13020`, backend/Core HTTP `18020`. `make core-run`은 `OTO_CORE_ADDR=0.0.0.0:18020`, `make client-run-web`은 preview `13020`을 사용한다. `OTO_RUNNER_RELEASE_BASE_URL`은 HTTPS release URL 기준을 유지하되 private host 원문은 기록하지 않는다. | | `appsok` | 기본 local 테스트 evidence는 standard remote Mac runner 기준. 현재 checkout의 `git diff --check`와 문법 수준 확인은 preflight로만 사용 | `ssh toki@toki-labs.com`, `$HOME/docker/services/code-server/data/volume/workspace/appsok` | Flutter/macOS build는 public port 없음. Flutter web preview가 필요하면 frontend `13050`을 사용한다. Jenkins/ADB/Xcode/Keychain credential 원문은 tracked 문서에 쓰지 않는다. | | `proto-socket` | same-language/cross-language test matrix, examples, per-language runners | Dart web/Chrome fallback: `ssh toki@toki-labs.com`, `~/agent-work/proto-socket-dart-web` | runtime 포트 없음. fixed crosstest local port `29090-29899`는 workspace 표준 예외. 예제 `9090`은 제품 host publish 포트로 보지 않는다. | diff --git a/.workspace-ops/docs/ports.md b/.workspace-ops/docs/ports.md index 7df56e6..f69780b 100644 --- a/.workspace-ops/docs/ports.md +++ b/.workspace-ops/docs/ports.md @@ -34,6 +34,7 @@ | `alt` | `13030` | `18030`, `18031` | - | `19030` optional | - | `15430`, `16330` | 기존 API/worker 포트와 migration note 필요 | | `nexo` | `13040` | `18065`, `18066` 유지 | - | - | - | compose-internal 우선 | 변경 필요 시 `18040` 계열 후보. `18065/18066`은 compatibility baseline | | `appsok` | `13050` | - | - | - | - | - | remote Mac runner 중심. 일반 Flutter/macOS build는 public port 없음 | +| `gito` | `13060` | `18060` | - | `19060` optional | - | `15460`, `16360` | nomadcode처럼 remote runner 기준. Core 내부/default `8080`은 유지하고 host publish/direct smoke만 gito-owned slot 사용 | | `proto-socket` | - | - | - | test runner `29090-29899` | - | - | 운영 포트가 아니라 crosstest local fixed port 예외 | ## 제외 또는 host 의존 @@ -55,3 +56,4 @@ | `oto` | `agent-roadmap/phase/independent-control-plane/milestones/workspace-port-env-standardization.md` | | `proto-socket` | `agent-roadmap/milestones/workspace-port-env-standardization.md` | | `appsok` | 현재 workspace-level inventory로 관리. 프로젝트 milestone 확인 시 추가 | +| `gito` | 현재 workspace-level inventory와 `agent-test/local/` 기준으로 관리. 프로젝트 milestone 필요 시 추가 | diff --git a/.workspace-ops/docs/remote-runners.md b/.workspace-ops/docs/remote-runners.md index 4eebb24..60da53e 100644 --- a/.workspace-ops/docs/remote-runners.md +++ b/.workspace-ops/docs/remote-runners.md @@ -11,6 +11,7 @@ | `iop` | `ssh toki@toki-labs.com` | `/Users/toki/agent-work/iop-dev` | Control Plane/Edge/Node/Client remote validation | Docker-in-Docker 없이 remote host/runtime 기준으로 검증한다. | | `nexo` | `ssh toki@toki-labs.com` | repo `~/agent-work/nexo`, compose `~/docker/agent-service/nexo/compose` | Mattermost core/push-proxy runtime validation | core `18065`, push-proxy `18066`은 compatibility baseline으로 둔다. | | `nomadcode` | remote Android runner host | `$HOME/agent-work/nomadcode` | Flutter/Android runner, sibling package integration | `../nexo/packages/messaging_flutter`, `../proto-socket/dart` sibling dependency를 전제로 한다. | +| `gito` | `ssh toki@toki-labs.com` | `$HOME/agent-work/gito` | Core Go, Flutter client, provider webhook/proto-socket, agent-shell runner validation | 기본 local 테스트 evidence는 remote runner 기준이다. Core internal/default `8080`은 유지하고 host 검증은 `18060`을 사용한다. | | `appsok` | `ssh toki@toki-labs.com` | `$HOME/docker/services/code-server/data/volume/workspace/appsok` | Flutter macOS/Xcode/ADB/Jenkins remote validation | Flutter web preview가 필요하면 `13050`을 사용한다. | | `proto-socket` | `ssh toki@toki-labs.com` | `~/agent-work/proto-socket-dart-web` | Dart web/Chrome fallback, WSS/SPKI wrapper | runtime service가 아니라 test harness 예외다. | | `oto` | `ssh toki@toki-labs.com` | `/Users/toki/agent-work/oto` | OTO runner/Core/client remote validation | 기본 local 테스트 evidence는 remote runner 기준이다. Core `18020`, Flutter web preview `13020`을 project-owned slot으로 사용한다. | @@ -32,6 +33,10 @@ | `nexo` | external core HTTP | `18065` | | `nexo` | push-proxy HTTP | `18066` | | `appsok` | Flutter web preview when needed | `13050` | +| `gito` | Flutter/code-server preview when needed | `13060` | +| `gito` | Core HTTP host publish/direct smoke | `18060` | +| `gito` | optional proto-socket/agent transport split | `19060` | +| `gito` | PostgreSQL/Redis host publish candidates | `15460`, `16360` | | `oto` | Core HTTP host publish | `18020` | | `oto` | Flutter web preview when needed | `13020` | | `proto-socket` | crosstest local fixed port range | `29090-29899` | diff --git a/.workspace-ops/docs/remote-test-environments.md b/.workspace-ops/docs/remote-test-environments.md index 1a222b1..4923568 100644 --- a/.workspace-ops/docs/remote-test-environments.md +++ b/.workspace-ops/docs/remote-test-environments.md @@ -21,6 +21,7 @@ | `iop` | `ssh toki@toki-labs.com`, code-server/remote runner | `/Users/toki/agent-work/iop-dev` | Control Plane, Edge, Node, Client, Docker compose, field/bootstrap 검증 | local/test: frontend `13000`, CP HTTP `18000`, DB/cache `15400/16300`; dev: frontend `13001`, CP HTTP `18001`, DB/cache `15401/16301` | local/test field baseline `18080/18081`, `19080/19081/19090`, metrics `19092`; dev wire/model candidates `19001/19002/19003`, `18082/18083`, metrics `19101` | Edge token 등 secret 원문은 원격 환경에서 주입하고 tracked 문서에 기록하지 않음 | | `nexo` | `ssh toki@toki-labs.com` | repo `~/agent-work/nexo`, compose `~/docker/agent-service/nexo/compose` | Mattermost core/push-proxy runtime, Flutter/Android, Detox, FCM/device evidence | core `18065`, push-proxy `18066` | Android Detox Metro는 `8081` 점유 시 `8088`; Flutter Web preview는 ignored `web-smoke.env` 값 기준 | Mattermost/FCM/test account 값은 `agent-test/local/secrets.md` 같은 ignored profile에서만 확인 | | `nomadcode` | `ssh toki@toki-labs.com` standard remote runner | `$HOME/agent-work/nomadcode` | Core, Flutter client, Android SDK runner, Mattermost/FCM 시나리오 | Flutter/code-server preview `13010`, Core compose host publish `18010:8080`, DB/cache 후보 `15410/16310` | sibling `../nexo/packages/messaging_flutter`, `../proto-socket/dart` 경로 전제 | Mattermost/FCM/signature 등 private input은 ignored local profile 기준 | +| `gito` | `ssh toki@toki-labs.com` standard remote runner | `$HOME/agent-work/gito` | Core Go, Flutter client, provider webhook/proto-socket smoke, agent-shell runner baseline | Flutter/code-server preview `13060`, Core host publish/direct HTTP `18060`, optional proto-socket/agent transport `19060`, DB/cache 후보 `15460/16360` | Core internal/default `8080`은 compatibility 경로. IOP field `18080/19080/19090`과 nexo `18065/18066`은 gito-owned slot으로 쓰지 않음 | Provider webhook secret, credential_ref, runner credential은 ignored local profile 기준 | | `proto-socket` | 기본은 local matrix; Dart.web Chrome 없을 때 remote fallback | `toki@toki-labs.com`, `~/agent-work/proto-socket-dart-web` | Dart.web/WSS Chrome fallback, SPKI wrapper, cross-language matrix 보조 | crosstest runner fixed range `29090-29899` | runtime service port 없음; 예제 `9090`은 제품/테스트 슬롯 아님 | runner 입력 secret 없음. SSH 인증은 local 계정/agent 환경 책임 | | `oto` | `ssh toki@toki-labs.com` standard remote runner | `/Users/toki/agent-work/oto` | OTO runner, Core HTTP, Flutter client/web preview, bootstrap/release validation | frontend/web preview `13020`, Core HTTP host publish `18020` | product fallback `127.0.0.1:8080`은 compatibility 경로. OTO-owned wire/agent transport port는 아직 확정하지 않음 | `OTO_RUNNER_RELEASE_BASE_URL`, enrollment token, private release host 원문은 tracked 문서에 기록하지 않음 | | `agent-shell` | 없음 | 없음 | Dart/Flutter package test | 없음 | package 자체 포트 없음. host 앱이 환경 소유 | 없음 | @@ -37,6 +38,7 @@ | `iop` dev profile | local/test stack이 원격 host에서 이미 `13000`, `18000`, `19080`, `19081`, `15400`, `16300`을 점유할 수 있음 | dev profile은 `.env.dev.example` 기준 `13001`, `18001`, `19001`, `19002`, `19003`, `15401`, `16301`을 사용하고 compose project/network를 분리한다. | | `oto` remote local profile | 제품 fallback `127.0.0.1:8080`과 workspace backend slot `18020`이 함께 존재함 | 테스트/원격 evidence는 `18020`을 기준으로 하고 `8080`은 product compatibility fallback으로만 문서화한다. | | `nexo` `18065/18066` | workspace backend 후보 `18040` 계열과 다름 | Mattermost compatibility baseline으로 유지한다. 신규 nexo-owned backend가 필요할 때만 `18040` 계열을 검토한다. | +| `gito` local test slots | 새 remote runner 기반 local 환경이 필요하지만 `nomadcode`, `oto`, `nexo`, `iop` 포트와 겹치면 안 됨 | gito-owned slot을 `13060/18060/19060/15460/16360`으로 둔다. Core 내부/default `8080`은 compatibility-only이며 IOP field baseline이나 nexo compatibility ports를 재사용하지 않는다. | | `proto-socket` `29090-29899` | 일반 runtime port가 아니라 test runner fixed range | workspace 예외 대역으로 유지하고 제품 host publish 표준화 대상에서 제외한다. | ## 변경 전 체크리스트 diff --git a/.workspace-ops/docs/secrets-sops.md b/.workspace-ops/docs/secrets-sops.md new file mode 100644 index 0000000..b0bda26 --- /dev/null +++ b/.workspace-ops/docs/secrets-sops.md @@ -0,0 +1,58 @@ +# Workspace SOPS Secret Management + +This guide defines workspace-level secret handling. It is guidance only; each +project still owns its runtime config and secret loading code. + +## Principles + +- Track encrypted secret material only when needed, using SOPS. +- Never track decrypted secret files or raw secret values. +- Keep local decryption identities and runtime `.env` files ignored. +- Document secret names, injection points, and validation paths, not values. +- Prefer project-local secret docs when they exist; use this guide for common + workspace expectations. + +## Recommended Layout + +| Item | Location | +|---|---| +| SOPS policy | project root `.sops.yaml` | +| Encrypted project secrets | project-owned path such as `secrets/*.sops.yaml` or an existing project convention | +| Local age/GPG identity | ignored local profile, never tracked | +| Runtime env file | ignored project-local `.env*` or documented remote runner injection | +| Workspace guidance | `.workspace-ops/docs/secrets-sops.md` | + +## Required Documentation For A Project + +When a project uses SOPS, its tracked guidance should state: + +- encrypted file path pattern +- recipient/key ownership at a high level +- runtime injection path +- validation command or smoke path +- which values must never be committed + +## Validation Examples + +Use examples like these without printing decrypted values: + +```bash +sops -d secrets/example.sops.yaml >/dev/null +``` + +```bash +APP_ENV=local bin/test +``` + +Remote runner validation should mention the runner and command class, not the +secret value. + +## Safety Checklist + +- [ ] No raw token, password, private key, signing material, webhook secret, or + private account value is tracked. +- [ ] Decrypted output paths are ignored. +- [ ] SOPS recipients are documented at the ownership level. +- [ ] Project runtime config loads secrets from the documented injection path. +- [ ] Build/Jenkins/OTO docs refer to this guide instead of duplicating secret + values. diff --git a/.workspace-ops/rules/common/rules.md b/.workspace-ops/rules/common/rules.md index 46c3ac7..8a6c68c 100644 --- a/.workspace-ops/rules/common/rules.md +++ b/.workspace-ops/rules/common/rules.md @@ -6,6 +6,7 @@ - 분석 대상 하위 repository는 workspace root `.gitignore`에서 ignore되는 프로젝트 폴더 중 `.workspace-ops/config/target-excludes.txt`에 없는 경로만 대상으로 한다. - 하위 repository를 변경해야 할 때는 해당 repository의 진입 파일과 `agent-ops/rules/project/rules.md`를 먼저 확인한다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 하위 skill을 사용한다. +- workspace 공통 관리 작업은 `.workspace-ops/skills/router.md`를 읽고 해당 domain rule과 skill을 선택한다. - `.workspace-ops/**`는 workspace 운영 도구이므로 하위 프로젝트 분석 대상에서 제외한다. 단, skill 또는 rule을 사용하기 위해 명시적으로 필요한 파일은 읽을 수 있다. - `.tmp/**`, `.antigravitycli/**`, `**/.agent-cache/**`, `**/.git/**`, `**/node_modules/**`, `**/build/**`, `**/dist/**`, `**/.dart_tool/**`, `**/coverage/**`는 일반 분석 대상에서 제외한다. - `agent-task/archive/**`와 `agent-roadmap/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다. @@ -24,9 +25,12 @@ | 요청 예시 | 요청 성격 | SKILL.md | |----------|----------|----------| | 오늘 작업 평가해줘, 오늘 평가해줘, 일간 리뷰, daily review | 오늘 작업 평가 | `.workspace-ops/skills/daily-subproject-review/SKILL.md` | +| iop 지난주 작업 내용 알려줘, iop 주간 작업을 요약해줘, iop 주간 작업 요약, iop 주간 작업을 정리해줘, iop 주간 작업 정리, iop 작업 요약, IOP weekly work summary | IOP 범위 주간 작업 요약 | `.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md` | | 주간 작업, 이번주 작업 정리, 지난 일주일 작업 요약, weekly work summary | 이번 주 작업 요약 | `.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md` | | 이번주 작업 평가해줘, 이번주 평가해줘, 주간 분석, weekly review, cross-repo 점검 | 이번 주 작업 평가 | `.workspace-ops/skills/weekly-subproject-review/SKILL.md` | | 이 작업 시작해도 돼?, 구현 전 점검, 시작 가능 여부, pre-implementation review | 큰 구현 전 점검 | `.workspace-ops/skills/pre-implementation-review/SKILL.md` | +| SOPS, 시크릿 관리, secret guide, `.sops.yaml` | workspace 시크릿 관리 | `.workspace-ops/skills/secrets-management/SKILL.md` | +| Jenkins, OTO, 빌드 관리, build guide, artifact/evidence | workspace 빌드 관리 | `.workspace-ops/skills/build-management/SKILL.md` | ## 진입 파일 diff --git a/.workspace-ops/rules/domains/secrets/rules.md b/.workspace-ops/rules/domains/secrets/rules.md new file mode 100644 index 0000000..0ef2591 --- /dev/null +++ b/.workspace-ops/rules/domains/secrets/rules.md @@ -0,0 +1,36 @@ +# Workspace Secrets Domain Rules + +## Scope + +This domain covers workspace-level guidance for secret handling with SOPS. +It does not store raw secret values and does not replace project-owned secret +loading code. + +## Rules + +- Use SOPS for encrypted secret files when a project needs tracked secret + material. +- Do not write raw tokens, passwords, private keys, account ids, signing + material, or webhook secrets in tracked workspace docs. +- Keep local key material, age identities, GPG private keys, `.env` files, and + decrypted secret output in ignored local files. +- Project docs may describe secret names, injection paths, owners, and expected + runtime variables, but not values. +- `.workspace-ops/docs/secrets-sops.md` is the workspace guide for SOPS usage. +- `.workspace-ops/templates/secrets-sops.md` is the starter guide for a newly + added project that needs SOPS guidance. +- If a project already has stronger local `agent-ops` or `agent-test/local` + secret rules, follow the project-local rule first and keep workspace docs as + inventory/guidance only. +- Secret changes should mention the validation path without exposing values, + for example `sops -d `, app config load test, or remote runner smoke. + +## Routing + +Use `.workspace-ops/skills/secrets-management/SKILL.md` for requests such as: + +- SOPS 기준 정리 +- 시크릿 관리 가이드 추가 +- 프로젝트 secret 문서 기본형 추가 +- raw secret 노출 여부 점검 +- `.sops.yaml` 또는 encrypted secret layout 검토 diff --git a/.workspace-ops/rules/project/rules.md b/.workspace-ops/rules/project/rules.md index 9b1d1a7..4956f45 100644 --- a/.workspace-ops/rules/project/rules.md +++ b/.workspace-ops/rules/project/rules.md @@ -29,9 +29,21 @@ | 요청 예시 | 요청 성격 | SKILL.md | |----------|----------|----------| | 오늘 작업 평가해줘 / 오늘 평가해줘 / 일간 분석 / daily | 오늘 작업 평가 | `.workspace-ops/skills/daily-subproject-review/SKILL.md` | +| iop 지난주 작업 내용 알려줘 / iop 주간 작업을 요약해줘 / iop 주간 작업 요약 / iop 주간 작업을 정리해줘 / iop 주간 작업 정리 / iop 작업 요약 / IOP weekly work summary | IOP 범위 주간 작업 요약 | `.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md` | | 주간 작업 / 이번주 작업 정리 / 지난 일주일 작업 요약 / weekly work summary | 이번 주 작업 요약 | `.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md` | | 이번주 작업 평가해줘 / 이번주 평가해줘 / 주간 분석 / weekly / cross-repo 점검 | 이번 주 작업 평가 | `.workspace-ops/skills/weekly-subproject-review/SKILL.md` | | 이 작업 시작해도 돼? / 구현 전 점검 / 시작 가능 여부 / pre-implementation | 큰 구현 전 점검 | `.workspace-ops/skills/pre-implementation-review/SKILL.md` | +| SOPS / 시크릿 관리 / secret guide / `.sops.yaml` | workspace 시크릿 관리 | `.workspace-ops/skills/secrets-management/SKILL.md` | +| Jenkins / OTO / 빌드 관리 / build guide / artifact/evidence | workspace 빌드 관리 | `.workspace-ops/skills/build-management/SKILL.md` | + +workspace 공통 관리 요청은 먼저 `.workspace-ops/skills/router.md`를 확인해 domain rule과 skill을 고른다. + +## 공통 관리 도메인 + +| 도메인 | Rules | Guide | +|--------|-------|-------| +| secrets | `.workspace-ops/rules/domains/secrets/rules.md` | `.workspace-ops/docs/secrets-sops.md` | +| build | `.workspace-ops/rules/domains/build/rules.md` | `.workspace-ops/docs/build-jenkins-oto.md` | ## 출력 기준 diff --git a/.workspace-ops/skills/build-management/SKILL.md b/.workspace-ops/skills/build-management/SKILL.md new file mode 100644 index 0000000..c70775f --- /dev/null +++ b/.workspace-ops/skills/build-management/SKILL.md @@ -0,0 +1,57 @@ +--- +name: build-management +version: 1.0.0 +description: workspace-level build-management guidance skill for Jenkins and OTO-backed build/deploy flows. Use when adding or reviewing common build guidance, artifact/evidence conventions, or project starter build docs. +--- + +# Build Management + +## Purpose + +Keep Jenkins and OTO build/deploy guidance consistent across the workspace while +preserving each project's own build entrypoints. + +## When To Use + +- The user asks about Jenkins build guidance. +- The user asks about OTO build/deploy responsibility. +- A project needs a starter build-management guide. +- A build flow needs shared evidence, artifact, remote runner, or credential + handling guidance. + +## Required Reads + +- `.workspace-ops/rules/common/rules.md` +- `.workspace-ops/rules/domains/build/rules.md` +- `.workspace-ops/docs/build-jenkins-oto.md` +- `.workspace-ops/templates/build-jenkins-oto.md` when creating a project + starter guide +- `.workspace-ops/docs/remote-test-environments.md` when remote runner behavior + matters + +## Procedure + +1. Identify the project-owned build entrypoints before discussing Jenkins or + OTO. +2. Separate responsibilities: project commands, Jenkins orchestration, OTO + build/deploy agent behavior, remote runner, artifact storage, and evidence. +3. Link credential handling back to the SOPS/secret guidance instead of + repeating secret values. +4. If adding a starter guide for a project, use the workspace template and fill + only confirmed project paths and commands. +5. Note unknown Jenkins job names, OTO commands, or artifact paths as + "확인 필요" instead of inventing them. + +## Output + +- State the build owner and orchestration owner. +- List project commands, Jenkins/OTO responsibilities, artifact/evidence + outputs, and credential injection boundaries. +- Include verification commands or smoke paths where known. + +## Do Not + +- Do not make Jenkins or OTO the source of truth for project build behavior when + the project already has local entrypoints. +- Do not store credentials or private job URLs in tracked docs. +- Do not add project-local build files unless the user asked for implementation. diff --git a/.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md b/.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md new file mode 100644 index 0000000..e566b0f --- /dev/null +++ b/.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md @@ -0,0 +1,145 @@ +--- +name: iop-weekly-subproject-work-summary +version: 1.0.0 +description: IOP 관련 핵심 repository만 대상으로 기존 weekly-subproject-work-summary를 상속해 지난주 또는 최근 1주 git 작업 내용을 평가 없이 상위 bullet은 repo명, 하위 bullet은 기능/작업 영역 단위의 주요 내용인 간단한 목록으로 정리/요약하는 래퍼 스킬. 사용자가 "iop 지난주 작업 내용 알려줘", "iop 주간 작업을 요약해줘", "iop 주간 작업을 정리해줘", "iop 작업 요약", "IOP weekly work summary"처럼 IOP 범위의 작업 내용 정리나 요약을 요청할 때 사용한다. +--- + +# IOP Weekly Subproject Work Summary + +## 목적 + +기존 `.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md`를 베이스로 사용하되, 분석 대상을 IOP 관련 핵심 repository로 제한한다. +평가, 점수, 속도 비교, 품질 판정은 하지 않고, git 기록에서 확인되는 작업 내용을 repo별 기능/작업 영역 bullet로만 정리한다. +기본 독자는 내부 주간 공유를 받는 사람으로 보고, 구현자가 아니어도 이해할 수 있는 기능명과 작업 축 중심으로 쓴다. + +## 상속 규칙 + +1. 먼저 베이스 스킬 `.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md`를 읽고 따른다. +2. 베이스 스킬이 요구하는 shared reference도 그대로 읽는다. + - `.workspace-ops/shared/target-discovery.md` +3. 이 스킬의 오버라이드 규칙과 베이스 스킬이 충돌하면 이 스킬을 우선한다. +4. 베이스 스킬의 수집 원칙과 평가 금지 원칙은 유지하되, 출력 형식은 이 스킬의 단순 nested bullet 형식으로 오버라이드한다. + +## 오버라이드 + +### 대상 repository + +아래 repository만 작업 내용 요약 대상으로 삼는다. + +- `agent-shell` +- `agent-framework` +- `iop` +- `nexo` +- `oto` +- `proto-socket` + +로컬 workspace에 `agent-framework`가 없고 `agentic-framework`가 있으면 `agent-framework` 요청은 `agentic-framework`로 해석한다. +결과에는 실제 확인한 경로를 명확히 쓴다. + +### 기간 해석 + +- 사용자 요청에 `지난주`가 들어 있으면 rolling 7 days가 아니라 직전 calendar week를 기준으로 `since`와 `until`을 계산한다. +- timezone이 명시되지 않았으면 현재 실행 환경의 `date -Is` 기준으로 계산하고, 최종 답변에는 사용한 절대 날짜를 적는다. +- 사용자가 기간을 명시하면 그 기간을 우선한다. + +예: + +```bash +.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh /config/workspace "2026-06-08 00:00" "2026-06-14 23:59:59" +``` + +### 포함/제외 기준 + +- `git log --branches --remotes` 기준으로 기간 내 commit을 수집한다. +- 분석 기간 동안 git commit이 없는 repository는 출력에 포함하지 않는다. +- 분석 기간 동안 작업 내용 요약 대상 commit이 0개인 repository는 출력에 포함하지 않는다. +- 변경된 파일이 모두 agent-ops sync path인 repository는 출력에 포함하지 않는다. +- 하나의 commit에 sync path와 제품/운영 payload path가 함께 있으면 작업 내용 요약 대상 commit으로 본다. +- 이 경우 sync path 자체가 아니라 제품/운영 payload path를 중심으로 요약한다. +- 미커밋 변경은 기본 출력에 포함하지 않는다. +- `agent-task/archive/**`와 `agent-roadmap/archive/**`의 파일 내용은 읽지 않는다. 단, git 변경 경로 집계에서 archive 경로가 나타나는 것은 작업 정리/아카이브 흐름으로만 요약할 수 있다. + +agent-ops sync path는 다음으로 본다. + +- `agent-ops/**` +- `.claude/**` +- `AGENTS.md` +- `GEMINI.md` +- `CLAUDE.md` +- `.cursorrules` +- `.clinerules` + +### 수집 방법 + +기본 수집은 이 스킬의 `scripts/collect.sh`를 사용한다. + +```bash +.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh /config/workspace "7 days ago" +``` + +기간을 명시받으면 두 번째 인자로 `since`, 세 번째 인자로 `until`을 전달한다. + +```bash +.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh /config/workspace "2026-06-08 00:00" "2026-06-14 23:59:59" +``` + +스크립트 출력에는 작업 내용 요약 대상 commit이 있는 repo만 나타난다. +출력에 없는 target repo는 최종 bullet 목록에 포함하지 않는다. + +## 출력 작성 규칙 + +- 최종 출력은 상위 bullet이 repository 이름이고, 하위 bullet이 기능/작업 영역 단위의 주요 내용인 nested bullet 목록만 사용한다. +- `구분`, `내용`, `목표`, `확인된 작업자`, `완성 산출물`, `보고용 요약`, `리스크`, `총평` 같은 섹션이나 라벨은 쓰지 않는다. +- 출력 대상 repo별로 하위 bullet은 보통 2-5개로 압축한다. +- 하위 bullet은 git commit 제목과 변경 경로에서 확인되는 기능, 역량, 작업 영역 수준으로 쓴다. +- 하위 bullet은 한 줄짜리 명사구로 쓴다. 설명 문장, 세부 구현 열거, commit 제목 재작성에 가까운 표현은 피한다. +- 사용자가 세부 구현 내용을 명시적으로 요청하지 않았으면 파일명, 테스트명, class/function/module 내부 구조, adapter 세부 이름, config key, 마일스톤 번호, 세부 task id 같은 구현 디테일은 쓰지 않는다. +- 여러 commit이 같은 기능 목표를 향하면 하나의 기능 bullet로 묶는다. +- roadmap, task archive, milestone 정리는 제품 기능 작업과 별개로 의미 있는 운영 작업일 때만 `로드맵/작업 정리`처럼 넓은 단위로 쓴다. +- repo별로 제품 기능 bullet을 먼저 쓰고, 운영/로드맵 정리는 필요할 때 마지막에 둔다. +- 좋은 예: + - `inference provider와 모델 serving 확장` + - `edge/node 런타임 동시성, 큐, 스케줄링 기능` + - `agent 등록과 capability 경계 기능` + - `Flutter Web 알림 기능과 알림 라우팅 개선` + - `large payload 처리 최적화` +- 피할 예: + - `OpenAI compatible adapter implementation and test fixes` + - `configs/edge.yaml과 server_test.go 갱신` + - `m-node-multi-target-serving-foundation G07/G08 작업` + - `provider availability capacity queue foundation` +- 전체 총평, 평가표, 속도표, 품질표, 점수는 쓰지 않는다. +- `지난주` 요청이라도 날짜 범위는 본문 앞뒤 설명으로 길게 쓰지 말고, 사용자가 날짜를 요구한 경우에만 한 줄로 덧붙인다. +- 작업이 없는 repo나 agent-ops sync-only repo는 목록에 넣지 않는다. + +## 출력 형식 + +```markdown +- repo-name + - 기능/작업 영역 + - 기능/작업 영역 + +- repo-name + - 기능/작업 영역 + - 기능/작업 영역 +``` + +## 실행 결과 검증 + +- [ ] 베이스 `weekly-subproject-work-summary`를 먼저 읽었는가 +- [ ] 대상이 `agent-shell`, `agent-framework`/`agentic-framework`, `iop`, `nexo`, `oto`, `proto-socket`으로 제한됐는가 +- [ ] commit이 없는 repo와 agent-ops sync-only repo를 출력에서 제외했는가 +- [ ] `지난주` 요청이면 rolling 7 days가 아니라 직전 calendar week 범위를 사용했는가 +- [ ] 상위 bullet은 repo명, 하위 bullet은 기능/작업 영역 수준의 주요 내용만 썼는가 +- [ ] 하위 bullet이 한 줄짜리 명사구이며 구현자가 아니어도 이해할 수 있는 수준인가 +- [ ] 사용자가 요구하지 않은 파일명, 테스트명, class/function/module 내부 구조, config key, 마일스톤 번호, 세부 task id 같은 구현 디테일을 제거했는가 +- [ ] `구분`, `내용`, `목표`, `확인된 작업자`, `완성 산출물` 같은 라벨을 쓰지 않았는가 +- [ ] 평가표, 점수, 속도/품질 판정을 쓰지 않았는가 +- [ ] 미커밋 변경을 기본 출력에 포함하지 않았는가 +- [ ] archive 파일 내용을 직접 읽지 않았는가 + +## 금지 사항 + +- `iop 지난주 작업 내용` 요청을 주간 평가/분석 스킬로 라우팅하지 않는다. +- 대상 6개 repo 밖의 repository를 사용자가 요청하지 않았는데 함께 요약하지 않는다. +- 작업 요약을 주간 평가로 바꾸지 않는다. diff --git a/.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh b/.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh new file mode 100755 index 0000000..0d830d8 --- /dev/null +++ b/.workspace-ops/skills/iop-weekly-subproject-work-summary/scripts/collect.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="${1:-$(cd "$SCRIPT_DIR/../../../.." && pwd)}" +SINCE="${2:-7 days ago}" +UNTIL="${3:-}" + +if [[ "$WORKSPACE_ROOT" != "/" ]]; then + WORKSPACE_ROOT="${WORKSPACE_ROOT%/}" +fi + +TARGET_REPOS=( + "agent-shell" + "agent-framework" + "iop" + "nexo" + "oto" + "proto-socket" +) + +resolve_repo_rel() { + local requested="$1" + + if [[ -d "$WORKSPACE_ROOT/$requested/.git" ]]; then + printf '%s\n' "$requested" + return 0 + fi + + if [[ "$requested" == "agent-framework" && -d "$WORKSPACE_ROOT/agentic-framework/.git" ]]; then + printf '%s\n' "agentic-framework" + return 0 + fi + + return 1 +} + +is_sync_path() { + local path="$1" + + case "$path" in + agent-ops/*|.claude/*|AGENTS.md|GEMINI.md|CLAUDE.md|.cursorrules|.clinerules) + return 0 + ;; + esac + + return 1 +} + +commit_paths() { + local repo="$1" + local sha="$2" + + git -C "$repo" diff-tree --root --no-commit-id --name-only -r "$sha" +} + +is_summary_commit() { + local repo="$1" + local sha="$2" + local path + + while IFS= read -r path; do + [[ -z "$path" ]] && continue + if ! is_sync_path "$path"; then + return 0 + fi + done < <(commit_paths "$repo" "$sha") + + return 1 +} + +path_bucket() { + awk ' + NF { + n = split($0, a, "/") + if (n == 1) { + p = a[1] + } else if (a[1] == "agent-task" || a[1] == "agent-roadmap" || a[1] == "agent-ops") { + p = a[1] "/" a[2] + } else { + p = a[1] "/" a[2] + } + c[p]++ + } + END { + for (p in c) print c[p], p + } + ' +} + +shortstat_for_commits() { + local repo="$1" + shift + local sha + + for sha in "$@"; do + git -C "$repo" show --shortstat --pretty=tformat: "$sha" + done | + awk ' + /files? changed/ { + files += $1 + for (i = 1; i <= NF; i++) { + if ($i == "insertion(+)" || $i == "insertions(+)") ins += $(i - 1) + if ($i == "deletion(-)" || $i == "deletions(-)") del += $(i - 1) + } + } + END { + printf "files_changed_sum=%d insertions=%d deletions=%d\n", files, ins, del + } + ' +} + +log_args=(--branches --remotes --since="$SINCE") +if [[ -n "$UNTIL" ]]; then + log_args+=(--until="$UNTIL") +fi + +for requested in "${TARGET_REPOS[@]}"; do + if ! rel="$(resolve_repo_rel "$requested")"; then + continue + fi + + repo="$WORKSPACE_ROOT/$rel" + mapfile -t all_shas < <(git -C "$repo" log "${log_args[@]}" --format='%H' | sort -u) + ((${#all_shas[@]} > 0)) || continue + + summary_shas=() + for sha in "${all_shas[@]}"; do + if is_summary_commit "$repo" "$sha"; then + summary_shas+=("$sha") + fi + done + + ((${#summary_shas[@]} > 0)) || continue + + echo "## $rel" + if [[ "$requested" != "$rel" ]]; then + echo "requested_alias: $requested" + fi + + printf 'branch: ' + git -C "$repo" branch --show-current + + echo "total_commits_in_period: ${#all_shas[@]}" + echo "summary_commits: ${#summary_shas[@]}" + + authors="$(git -C "$repo" show --no-patch --format='%aN <%aE>' "${summary_shas[@]}" | sort -u)" + author_count="$(printf '%s\n' "$authors" | awk 'NF {c++} END {print c + 0}')" + echo "author_count: $author_count" + echo "authors:" + if [[ -n "$authors" ]]; then + printf '%s\n' "$authors" | sed 's/^/- /' + fi + + echo "subjects:" + git -C "$repo" show --no-patch --date=iso --format='%h | %ad | %s' "${summary_shas[@]}" + echo + + echo "top non-sync paths:" + for sha in "${summary_shas[@]}"; do + while IFS= read -r path; do + [[ -z "$path" ]] && continue + if ! is_sync_path "$path"; then + printf '%s\n' "$path" + fi + done < <(commit_paths "$repo" "$sha") + done | + path_bucket | + sort -nr | + head -n 16 + + echo "shortstat:" + shortstat_for_commits "$repo" "${summary_shas[@]}" + echo +done diff --git a/.workspace-ops/skills/router.md b/.workspace-ops/skills/router.md new file mode 100644 index 0000000..83a65ef --- /dev/null +++ b/.workspace-ops/skills/router.md @@ -0,0 +1,19 @@ +# Workspace Skill Router + +This router only covers workspace-level operations. Product repository work +still follows the target repository's own entry files and `agent-ops` rules. + +| Request | Skill | +|---|---| +| 오늘 작업 평가, 일간 리뷰, daily review | `.workspace-ops/skills/daily-subproject-review/SKILL.md` | +| iop 지난주 작업 내용 알려줘, iop 주간 작업을 요약해줘, iop 주간 작업 요약, iop 주간 작업을 정리해줘, iop 주간 작업 정리, iop 작업 요약, IOP weekly work summary | `.workspace-ops/skills/iop-weekly-subproject-work-summary/SKILL.md` | +| 주간 작업, 이번주 작업 정리, weekly work summary | `.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md` | +| 이번주 작업 평가, 주간 분석, cross-repo 점검 | `.workspace-ops/skills/weekly-subproject-review/SKILL.md` | +| 구현 전 점검, 시작 가능 여부, pre-implementation review | `.workspace-ops/skills/pre-implementation-review/SKILL.md` | +| SOPS, 시크릿 관리, secret guide, `.sops.yaml` | `.workspace-ops/skills/secrets-management/SKILL.md` | +| Jenkins, OTO, 빌드 관리, build guide, artifact/evidence | `.workspace-ops/skills/build-management/SKILL.md` | + +## Domain Rules + +- Secrets/SOPS work: `.workspace-ops/rules/domains/secrets/rules.md` +- Build/Jenkins/OTO work: `.workspace-ops/rules/domains/build/rules.md` diff --git a/.workspace-ops/skills/secrets-management/SKILL.md b/.workspace-ops/skills/secrets-management/SKILL.md new file mode 100644 index 0000000..1a3b81d --- /dev/null +++ b/.workspace-ops/skills/secrets-management/SKILL.md @@ -0,0 +1,56 @@ +--- +name: secrets-management +version: 1.0.0 +description: workspace-level SOPS and secret-management guidance skill. Use when adding or reviewing common secret handling guidance, SOPS layout, raw-secret safety, or project starter secret docs. +--- + +# Secrets Management + +## Purpose + +Keep workspace-level secret handling consistent without storing secret values in +tracked files. + +## When To Use + +- The user asks about SOPS usage or common secret management. +- A project needs a starter secret-management guide. +- A workspace guide must explain where secrets are injected and how they are + validated. +- A change may expose raw secret values in tracked docs. + +## Required Reads + +- `.workspace-ops/rules/common/rules.md` +- `.workspace-ops/rules/domains/secrets/rules.md` +- `.workspace-ops/docs/secrets-sops.md` +- `.workspace-ops/templates/secrets-sops.md` when creating a project starter + guide + +## Procedure + +1. Identify whether the request is workspace-level guidance or a project-local + implementation change. +2. If a project is involved, read its entry file and project secret/testing + rules before proposing project-local edits. +3. Keep values out of tracked files. Record names, owners, injection points, + encrypted file paths, and validation commands only. +4. If adding a new project starter guide, use the workspace template and adjust + project names/paths without inventing secret values. +5. Report any raw-secret risk as a blocking issue before other cleanup. + +## Output + +- State whether the result is workspace guidance, project-local guidance, or a + raw-secret safety finding. +- Include the files or paths that should hold encrypted secrets and ignored + local identities. +- Include the validation command or smoke path without exposing secret values. + +## Do Not + +- Do not write raw secrets, private endpoints, tokens, passwords, private keys, + or account identifiers into tracked files. +- Do not assume one global SOPS recipient for every project unless a tracked + policy already says so. +- Do not replace project-local secret loading rules with workspace guidance. diff --git a/.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md b/.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md index 62fe2bd..ae3b3f1 100644 --- a/.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md +++ b/.workspace-ops/skills/weekly-subproject-work-summary/SKILL.md @@ -1,20 +1,20 @@ --- name: weekly-subproject-work-summary version: 1.0.0 -description: workspace root 아래 여러 하위 Git repository의 최근 1주 작업 내용을 평가 없이 프로젝트별 bullet 목록으로 요약하는 주간 작업 정리 스킬. 사용자가 "주간 작업", "이번주 작업 정리", "지난 일주일 작업 요약", "weekly work summary"를 요청할 때 사용한다. "이번주 작업 평가"나 "주간 분석"처럼 평가가 필요한 요청은 weekly-subproject-review를 사용한다. +description: workspace root 아래 여러 하위 Git repository의 최근 1주 작업 내용을 평가 없이 샘플형 보고서 구조로 요약하는 주간 작업 정리 스킬. 사용자가 "주간 작업", "이번주 작업 정리", "지난 일주일 작업 요약", "weekly work summary"를 요청할 때 사용한다. "이번주 작업 평가"나 "주간 분석"처럼 평가가 필요한 요청은 weekly-subproject-review를 사용한다. --- # Weekly Subproject Work Summary ## 목적 -workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내용을 git 기반으로 수집하고, 사용자가 빠르게 읽을 수 있는 프로젝트별 bullet 요약으로 정리한다. +workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내용을 git 기반으로 수집하고, 사용자가 보고 문서에 바로 옮길 수 있는 샘플형 구조로 정리한다. 평가, 점수, 속도 비교, 품질 판정은 하지 않는다. ## 언제 호출할지 - 사용자가 "주간 작업", "이번주 작업 정리", "지난 일주일 작업 요약"을 요청할 때 -- 사용자가 평가보다 "무슨 작업이 있었는지"를 프로젝트별로 보고 싶어 할 때 +- 사용자가 평가보다 "무슨 작업이 있었는지"를 보고서형 구조로 보고 싶어 할 때 - 여러 하위 repository의 최근 1주 git 기록을 쉬운 문체로 압축해야 할 때 - "weekly work summary", "weekly work log"처럼 주간 작업 목록을 요청할 때 @@ -63,15 +63,24 @@ workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내 - 커밋 수나 라인 수를 중심으로 쓰지 말고, 사용자가 이해할 수 있는 작업 단위로 압축한다. 5. **출력 작성** - - 프로젝트 이름을 굵은 제목으로 쓰고, 아래에 `- 내용` bullet만 둔다. - - 한 repo당 보통 3-8개 bullet로 제한한다. + - 샘플 문서처럼 번호가 붙은 보고서 섹션으로 작성한다. + - `# 1. 프로젝트별 주간 작업`, `# 2. 단계별 산출물`, `# 3. 주요 리스크 및 고려사항`, `# 4. 보고용 요약` 순서를 유지한다. + - 1번 섹션에는 repo별 `## repo-name: 핵심 작업 주제` 블록을 만들고, 각 블록에 `구분`, `내용`, `목표`, `확인된 작업자`, `주요 작업`, `완성 산출물` 항목을 둔다. + - `확인된 작업자`는 git author 기준으로 확인 가능한 범위에서만 적고, 확실하지 않으면 `확인 불가`라고 쓴다. 사람 이름을 추정하지 않는다. + - `목표`는 git 기록에서 드러난 작업 방향을 1-2문장으로 중립 서술한다. 로드맵, 의도, 미래 일정을 추정하지 않는다. + - `주요 작업`은 repo당 보통 4-8개 bullet로 제한한다. + - `완성 산출물`은 확인된 변경 결과를 2-5개 bullet로 쓴다. 완료 여부가 불명확하면 `정리`, `초안`, `기반`처럼 확인 가능한 표현을 사용한다. - 작업이 거의 없는 repo도 생략하지 말고, 실제 변화가 agent-ops 동기화 중심이면 그렇게 짧게 쓴다. - - 전체 총평, 평가표, 속도표, 품질표, 점수, 위험/누락 섹션은 쓰지 않는다. + - 2번 섹션은 repo 또는 작업 단계 단위로 `구분`과 `주요 산출물`을 나열한다. + - 3번 섹션은 git 기록과 변경 경로에서 사실로 확인되는 운영 고려사항만 쓴다. 확인되는 항목이 없으면 `확인된 주요 리스크 없음`으로 짧게 마무리한다. + - 4번 섹션은 전체 작업 흐름을 3-5문단으로 요약한다. + - 전체 총평, 평가표, 속도표, 품질표, 점수는 쓰지 않는다. ## 문체 규칙 - 한국어로 작성한다. - 어렵지 않은 문장과 짧은 명사형 bullet을 사용한다. +- 샘플처럼 보고서 문체를 사용하되, 과장된 로드맵 문장이나 확인되지 않은 미래 계획은 만들지 않는다. - bullet 끝에 `함`, `했음`, `합니다`, `했습니다`를 붙이지 않는다. - 좋은 예: - `- inbound queue ordering을 여러 언어 게이트웨이에 반영` @@ -81,19 +90,95 @@ workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내 - `- inbound queue ordering을 반영함` - `- core HTTP server 파일을 분리했습니다` - `- 미커밋 수정 존재` -- "미커밋", "위험", "감점", "누락" 같은 평가성 표현은 사용자가 요청하지 않으면 쓰지 않는다. +- "미커밋", "감점", "누락" 같은 평가성 표현은 사용자가 요청하지 않으면 쓰지 않는다. +- `주요 리스크 및 고려사항` 섹션에서도 결함 판정이 아니라 후속 확인이 필요한 사실만 중립적으로 쓴다. ## 출력 형식 ```markdown -**repo-name** -- 작업 내용 -- 작업 내용 -- 작업 내용 +# 1. 프로젝트별 주간 작업 -**repo-name** -- 작업 내용 -- 작업 내용 +* * * +## repo-name: 핵심 작업 주제 + +구분 + +내용 + +목표 + +최근 1주 git 기록에서 확인된 작업 방향을 1-2문장으로 정리합니다. + +확인된 작업자 + +git author 기준 N명 + +주요 작업 + + * 작업 내용 + + * 작업 내용 + + * 작업 내용 + +완성 산출물 + + * 확인된 산출물 + + * 확인된 산출물 + +* * * +## repo-name: 핵심 작업 주제 + +구분 + +내용 + +목표 + +최근 1주 git 기록에서 확인된 작업 방향을 1-2문장으로 정리합니다. + +확인된 작업자 + +git author 기준 N명 + +주요 작업 + + * 작업 내용 + + * 작업 내용 + +완성 산출물 + + * 확인된 산출물 + +# 2. 단계별 산출물 + +구분 + +주요 산출물 + +repo-name + +핵심 산출물 요약 + +repo-name + +핵심 산출물 요약 + +* * * + +# 3. 주요 리스크 및 고려사항 + +## 고려사항 제목 + +git 기록과 변경 경로에서 사실로 확인되는 후속 확인 사항을 중립적으로 정리합니다. + +* * * + +# 4. 보고용 요약 + +전체 주간 작업 흐름을 3-5문단으로 정리합니다. ``` ## 실행 결과 검증 @@ -101,7 +186,9 @@ workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내 - [ ] `.workspace-ops/**`를 하위 프로젝트 작업량에 포함하지 않았는가 - [ ] `agent-task/archive/**`와 `agent-roadmap/archive/**`를 명시 요청 없이 읽지 않았는가 - [ ] 평가표, 점수, 속도 비교를 출력하지 않았는가 -- [ ] repo별 bullet 형식으로만 정리했는가 +- [ ] 샘플형 보고서 섹션 1-4를 순서대로 출력했는가 +- [ ] repo별 블록에 `목표`, `확인된 작업자`, `주요 작업`, `완성 산출물`을 포함했는가 +- [ ] 리스크/고려사항 섹션에 확인되지 않은 추정이나 품질 판정이 들어가지 않았는가 - [ ] bullet 끝에 `함`, `했음`, `했습니다`가 남아 있지 않은가 - [ ] 미커밋 상태를 기본 출력에 쓰지 않았는가 @@ -110,6 +197,7 @@ workspace root의 하위 Git repository를 대상으로 최근 1주 작업 내 - 분석 요청만 받은 상태에서 하위 repository 파일을 수정하지 않는다. - 주간 작업 요약을 주간 평가로 바꾸지 않는다. - 커밋 수나 라인 수만으로 작업 의미를 단정하지 않는다. +- 확인되지 않은 일정, 투입 인원, 완료 상태, 향후 계획을 추정하지 않는다. - checkpoint/stash성 ref를 일반 작업 커밋처럼 요약하지 않는다. - archive 디렉터리를 사용자가 명시하지 않았는데 읽지 않는다. - 하위 프로젝트 내부 캐시성 중첩 repository를 일반 관리 프로젝트처럼 요약하지 않는다. diff --git a/.workspace-ops/skills/weekly-subproject-work-summary/scripts/collect.sh b/.workspace-ops/skills/weekly-subproject-work-summary/scripts/collect.sh index 81f30e9..130d8aa 100755 --- a/.workspace-ops/skills/weekly-subproject-work-summary/scripts/collect.sh +++ b/.workspace-ops/skills/weekly-subproject-work-summary/scripts/collect.sh @@ -94,6 +94,14 @@ while IFS= read -r repo; do printf 'commits: ' git -C "$repo" log "${log_args[@]}" --format='%H' | sort -u | wc -l + authors="$(git -C "$repo" log "${log_args[@]}" --format='%aN <%aE>' | sort -u)" + author_count="$(printf '%s\n' "$authors" | awk 'NF {c++} END {print c + 0}')" + echo "author_count: $author_count" + echo "authors:" + if [[ -n "$authors" ]]; then + printf '%s\n' "$authors" | sed 's/^/- /' + fi + echo "subjects:" git -C "$repo" log "${log_args[@]}" --date=short --pretty=format:'%h | %ad | %s' echo diff --git a/.workspace-ops/templates/build-jenkins-oto.md b/.workspace-ops/templates/build-jenkins-oto.md new file mode 100644 index 0000000..033d634 --- /dev/null +++ b/.workspace-ops/templates/build-jenkins-oto.md @@ -0,0 +1,38 @@ +# Project Build Management + +This project follows the workspace build guide: +`.workspace-ops/docs/build-jenkins-oto.md`. + +## Build Entry Points + +| Purpose | Command | +|---|---| +| Test | 확인 필요 | +| Lint | 확인 필요 | +| Build | 확인 필요 | + +## Jenkins + +- Job class or naming rule: 확인 필요 +- Trigger policy: 확인 필요 +- Artifact output: 확인 필요 + +## OTO + +- OTO role: 확인 필요 +- Build/deploy action boundary: 확인 필요 +- Evidence output: 확인 필요 + +## Credentials + +Build credentials follow `.workspace-ops/docs/secrets-sops.md`. + +| Credential | Injection Path | +|---|---| +| 확인 필요 | 확인 필요 | + +## Evidence + +Record command/job class, branch/ref, environment class, result, artifact +identifier, and follow-up action. Do not record raw secrets or private tokenized +URLs. diff --git a/.workspace-ops/templates/entry-file.md b/.workspace-ops/templates/entry-file.md index e515591..95ce1b0 100644 --- a/.workspace-ops/templates/entry-file.md +++ b/.workspace-ops/templates/entry-file.md @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다. diff --git a/.workspace-ops/templates/secrets-sops.md b/.workspace-ops/templates/secrets-sops.md new file mode 100644 index 0000000..2c5de01 --- /dev/null +++ b/.workspace-ops/templates/secrets-sops.md @@ -0,0 +1,37 @@ +# Project Secret Management + +This project follows the workspace SOPS guide: +`.workspace-ops/docs/secrets-sops.md`. + +## Secret Policy + +- Raw secret values are never tracked. +- Encrypted secret files use SOPS when tracked secret material is required. +- Local decryption identities and decrypted outputs stay ignored. + +## Project Layout + +| Item | Path / Owner | +|---|---| +| SOPS policy | 확인 필요 | +| Encrypted secrets | 확인 필요 | +| Local identity | ignored local profile | +| Runtime injection | 확인 필요 | +| Validation | 확인 필요 | + +## Validation + +```bash +# Example only. Replace with the project-specific encrypted file. +sops -d >/dev/null +``` + +```bash +# Project-specific config or smoke command. + +``` + +## Notes + +- Document secret names and injection paths, not values. +- Link build credentials back to this guide rather than duplicating them. diff --git a/AGENTS.md b/AGENTS.md index e515591..95ce1b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다. diff --git a/CLAUDE.md b/CLAUDE.md index e515591..95ce1b0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다. diff --git a/GEMINI.md b/GEMINI.md index e515591..95ce1b0 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -6,4 +6,5 @@ - workspace 운영 도구, 룰, 스킬, 설정, sync 자료는 `.workspace-ops/`에서만 관리한다. - 분석 대상 탐색은 `.workspace-ops/shared/target-discovery.md`와 `.workspace-ops/config/target-excludes.txt`를 따른다. - 주기 분석, 주간 작업 요약, 주간 분석, 구현 전 점검은 `.workspace-ops/skills/` 아래 해당 `SKILL.md`를 사용한다. +- SOPS 시크릿 관리와 Jenkins/OTO 빌드 관리는 `.workspace-ops/skills/router.md`에서 해당 도메인으로 라우팅한다. - 루트 진입 파일 목록은 `.workspace-ops/config/entry-files.txt`에 둔다.