aiwf 0.3.22 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +146 -0
- package/CHANGELOG.md +49 -1
- package/README.ko.md +118 -309
- package/README.md +68 -254
- package/docs/modernization/BROWNFIELD-GREENFIELD.ko.md +105 -0
- package/docs/modernization/CLAUDE-PLAN-REVIEW-2026-10-03.ko.md +77 -0
- package/docs/modernization/CLI-PRODUCTIVITY-REVIEWED-2026-10-03.ko.md +177 -0
- package/docs/modernization/CLI-PRODUCTIVITY.ko.md +193 -0
- package/docs/modernization/CORE-PACKAGE-PLAN.md +7 -0
- package/docs/modernization/DEEP-REVERSE-ENGINEERING.ko.md +88 -0
- package/docs/modernization/DELEGATION-OPTIONAL.ko.md +57 -0
- package/docs/modernization/DIRECTION.ko.md +56 -0
- package/docs/modernization/FULL-TEST-2026-10-03.md +49 -0
- package/docs/modernization/LEGACY-REMOVAL-PLAN.md +9 -0
- package/docs/modernization/PILOT-RESULT-2026-10-03.ko.md +85 -0
- package/docs/modernization/PILOT-UC-001.ko.md +79 -0
- package/docs/modernization/PLAN.md +28 -0
- package/docs/modernization/SKILLS.ko.md +105 -0
- package/docs/modernization/SPRINTABLE.ko.md +47 -0
- package/docs/modernization/SYNC-DOCS-VALIDATION-2026-10-04.ko.md +38 -0
- package/docs/modernization/VALIDATION.md +79 -0
- package/docs/modernization/evidence/example-review-packet.json +115 -0
- package/docs/modernization/evidence/example-spec-pin.json +48 -0
- package/docs/modernization/evidence/full-test-20261003/claude-lint.md +22 -0
- package/docs/modernization/evidence/full-test-20261003/claude-review-retry.md +56 -0
- package/docs/modernization/evidence/full-test-20261003/codex-review-packet.json +159 -0
- package/docs/modernization/evidence/full-test-20261003/src/expense.mjs +40 -0
- package/docs/modernization/evidence/full-test-20261003/summary.json +106 -0
- package/docs/modernization/evidence/full-test-20261003/tests/expense.test.mjs +61 -0
- package/docs/modernization/evidence/local-pilot-20261003/README.ko.md +40 -0
- package/docs/modernization/evidence/local-pilot-20261003/execution.json +1055 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.stdout.txt +5 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.stdout.txt +6 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.stdout.txt +5 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.stdout.txt +6 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.json +23 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.stdout.txt +535 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.stdout.txt +5 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.stdout.txt +273 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.json +24 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.stdout.txt +7 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-service.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-service.stdout.txt +148 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-structure.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-structure.stdout.txt +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-check.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-check.stdout.txt +67 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-evidence.json +34 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.json +128 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.stdout.txt +128 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.json +54 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.stdout.txt +60 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-readback.json +15 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-service.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-service.stdout.txt +82 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-structure.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-structure.stdout.txt +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-check.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-check.stdout.txt +79 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-packet-refused.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-packet-refused.stdout.txt +7 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin-refresh.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin-refresh.stdout.txt +66 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin.json +60 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-structure.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-structure.stdout.txt +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-check.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-check.stdout.txt +73 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-evidence.json +34 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.json +134 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.stdout.txt +134 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-readback.json +15 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-service.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-service.stdout.txt +148 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-structure.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-structure.stdout.txt +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/node-version.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/node-version.stdout.txt +1 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/python-version.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/python-version.stdout.txt +1 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-evidence.json +34 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.json +134 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.stdout.txt +134 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-readback.json +15 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-service.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-service.stdout.txt +266 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-structure.stderr.txt +0 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-structure.stdout.txt +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/entity_model.md +33 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/glossary.md +9 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/plans/UC-001.md +20 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/requirements.md +10 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/test_cases/TC-001-submit-expense.md +37 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/test_cases/TC-002-description-limit.md +42 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/use_cases/UC-001-submit-expense.md +76 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/use_cases.puml +12 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/docs/vision.md +21 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/src/expense.mjs +48 -0
- package/docs/modernization/evidence/local-pilot-20261003/project/tests/expense.test.mjs +116 -0
- package/docs/modernization/evidence/local-pilot-20261003/scope.json +31 -0
- package/docs/modernization/reviews/2026-10-03-claude-cli/CONTRACTS.ko.md +122 -0
- package/docs/modernization/reviews/2026-10-03-claude-cli/DIRECTION.ko.md +84 -0
- package/examples/spec-workflow/README.md +54 -0
- package/examples/spec-workflow/docs/entity_model.md +33 -0
- package/examples/spec-workflow/docs/glossary.md +9 -0
- package/examples/spec-workflow/docs/requirements.md +10 -0
- package/examples/spec-workflow/docs/test_cases/TC-001-submit-expense.md +37 -0
- package/examples/spec-workflow/docs/use_cases/UC-001-submit-expense.md +63 -0
- package/examples/spec-workflow/docs/use_cases.puml +12 -0
- package/examples/spec-workflow/docs/vision.md +21 -0
- package/package.json +37 -104
- package/plugins/aiwf-angular-jpa/.claude-plugin/plugin.json +11 -0
- package/plugins/aiwf-angular-jpa/LICENSE +201 -0
- package/plugins/aiwf-angular-jpa/NOTICE +16 -0
- package/plugins/aiwf-angular-jpa/README.md +54 -0
- package/plugins/aiwf-angular-jpa/UPSTREAM.json +35 -0
- package/plugins/aiwf-angular-jpa/agents/uc-coverage.md +263 -0
- package/plugins/aiwf-angular-jpa/rules/mcp-servers.md +64 -0
- package/plugins/aiwf-angular-jpa/skills/coverage-check/SKILL.md +190 -0
- package/plugins/aiwf-angular-jpa/skills/flyway-migration/SKILL.md +119 -0
- package/plugins/aiwf-angular-jpa/skills/implement/SKILL.md +528 -0
- package/plugins/aiwf-angular-jpa/skills/implement/references/module-layout.md +95 -0
- package/plugins/aiwf-angular-jpa/skills/playwright-test/SKILL.md +360 -0
- package/plugins/aiwf-angular-jpa/skills/spring-boot-test/SKILL.md +504 -0
- package/plugins/aiwf-angular-jpa/skills/vitest-test/SKILL.md +309 -0
- package/plugins/aiwf-blazor-dotnet/.claude-plugin/plugin.json +11 -0
- package/plugins/aiwf-blazor-dotnet/LICENSE +201 -0
- package/plugins/aiwf-blazor-dotnet/NOTICE +16 -0
- package/plugins/aiwf-blazor-dotnet/README.md +53 -0
- package/plugins/aiwf-blazor-dotnet/UPSTREAM.json +31 -0
- package/plugins/aiwf-blazor-dotnet/rules/mcp-servers.md +25 -0
- package/plugins/aiwf-blazor-dotnet/skills/bunit-test/SKILL.md +110 -0
- package/plugins/aiwf-blazor-dotnet/skills/dotnet-test/SKILL.md +108 -0
- package/plugins/aiwf-blazor-dotnet/skills/ef-migration/SKILL.md +43 -0
- package/plugins/aiwf-blazor-dotnet/skills/implement/SKILL.md +149 -0
- package/plugins/aiwf-blazor-dotnet/skills/playwright-test/SKILL.md +130 -0
- package/plugins/aiwf-core/.claude-plugin/plugin.json +11 -0
- package/plugins/aiwf-core/LICENSE +201 -0
- package/plugins/aiwf-core/NOTICE +20 -0
- package/plugins/aiwf-core/README.md +38 -0
- package/plugins/aiwf-core/UPSTREAM.json +50 -0
- package/plugins/aiwf-core/skills/entity-model/SKILL.md +160 -0
- package/plugins/aiwf-core/skills/entity-model/references/REFERENCE.md +36 -0
- package/plugins/aiwf-core/skills/requirements/SKILL.md +157 -0
- package/plugins/aiwf-core/skills/requirements/references/REFERENCE.md +70 -0
- package/plugins/aiwf-core/skills/requirements/references/glossary.md +7 -0
- package/plugins/aiwf-core/skills/reverse-engineer/SKILL.md +509 -0
- package/plugins/aiwf-core/skills/reverse-engineer/references/stack-signals.md +210 -0
- package/plugins/aiwf-core/skills/spec-review/SKILL.md +197 -0
- package/plugins/aiwf-core/skills/spec-review/references/lint-codes.md +63 -0
- package/plugins/aiwf-core/skills/spec-review/references/review-checklist.md +189 -0
- package/plugins/aiwf-core/skills/spec-review/scripts/spec_lint.py +1216 -0
- package/plugins/aiwf-core/skills/test-case/SKILL.md +138 -0
- package/plugins/aiwf-core/skills/test-case/references/example-process.bpmn +118 -0
- package/plugins/aiwf-core/skills/test-case/references/example.md +38 -0
- package/plugins/aiwf-core/skills/test-case/references/test-case.md +35 -0
- package/plugins/aiwf-core/skills/test-case/scripts/bpmn_paths.py +542 -0
- package/plugins/aiwf-core/skills/use-case-diagram/SKILL.md +99 -0
- package/plugins/aiwf-core/skills/use-case-spec/SKILL.md +257 -0
- package/plugins/aiwf-core/skills/use-case-spec/references/clarify-checklist.md +70 -0
- package/plugins/aiwf-core/skills/use-case-spec/references/example.md +88 -0
- package/plugins/aiwf-core/skills/use-case-spec/references/format-spec.md +246 -0
- package/plugins/aiwf-core/skills/use-case-spec/references/use-case.md +50 -0
- package/plugins/aiwf-core/skills/use-case-spec/scripts/validate_use_case.py +941 -0
- package/plugins/aiwf-delegate-claude/.claude-plugin/plugin.json +9 -0
- package/{src/lib/resources/templates/npm-library/template → plugins/aiwf-delegate-claude}/LICENSE +2 -2
- package/plugins/aiwf-delegate-claude/NOTICE +4 -0
- package/plugins/aiwf-delegate-claude/README.md +10 -0
- package/plugins/aiwf-delegate-claude/plugin.json +13 -0
- package/plugins/aiwf-delegate-claude/skills/delegate-claude/LICENSE +21 -0
- package/plugins/aiwf-delegate-claude/skills/delegate-claude/NOTICE +4 -0
- package/plugins/aiwf-delegate-claude/skills/delegate-claude/SKILL.md +49 -0
- package/plugins/aiwf-delegate-claude/skills/delegate-claude/agents/openai.yaml +2 -0
- package/plugins/aiwf-delegate-codex/.claude-plugin/plugin.json +9 -0
- package/plugins/aiwf-delegate-codex/LICENSE +21 -0
- package/plugins/aiwf-delegate-codex/NOTICE +4 -0
- package/plugins/aiwf-delegate-codex/README.md +10 -0
- package/plugins/aiwf-delegate-codex/plugin.json +13 -0
- package/plugins/aiwf-delegate-codex/skills/delegate-codex/LICENSE +21 -0
- package/plugins/aiwf-delegate-codex/skills/delegate-codex/NOTICE +4 -0
- package/plugins/aiwf-delegate-codex/skills/delegate-codex/SKILL.md +47 -0
- package/plugins/aiwf-delegate-codex/skills/delegate-codex/agents/openai.yaml +2 -0
- package/plugins/aiwf-nestjs-nextjs/.claude-plugin/plugin.json +11 -0
- package/plugins/aiwf-nestjs-nextjs/LICENSE +201 -0
- package/plugins/aiwf-nestjs-nextjs/NOTICE +16 -0
- package/plugins/aiwf-nestjs-nextjs/README.md +53 -0
- package/plugins/aiwf-nestjs-nextjs/UPSTREAM.json +32 -0
- package/plugins/aiwf-nestjs-nextjs/rules/mcp-servers.md +59 -0
- package/plugins/aiwf-nestjs-nextjs/skills/drizzle-migration/SKILL.md +222 -0
- package/plugins/aiwf-nestjs-nextjs/skills/implement/SKILL.md +393 -0
- package/plugins/aiwf-nestjs-nextjs/skills/implement/references/project-layout.md +158 -0
- package/plugins/aiwf-nestjs-nextjs/skills/nest-test/SKILL.md +300 -0
- package/plugins/aiwf-nestjs-nextjs/skills/playwright-test/SKILL.md +245 -0
- package/plugins/aiwf-nestjs-nextjs/skills/react-test/SKILL.md +217 -0
- package/plugins/aiwf-spec/.claude-plugin/plugin.json +9 -0
- package/plugins/aiwf-spec/LICENSE +201 -0
- package/plugins/aiwf-spec/NOTICE +20 -0
- package/plugins/aiwf-spec/README.md +36 -0
- package/plugins/aiwf-spec/skills/sync-docs/SKILL.md +47 -0
- package/plugins/aiwf-spec/skills/workflow/SKILL.md +42 -0
- package/plugins/aiwf-vaadin-jooq/.claude-plugin/plugin.json +11 -0
- package/plugins/aiwf-vaadin-jooq/LICENSE +201 -0
- package/plugins/aiwf-vaadin-jooq/NOTICE +16 -0
- package/plugins/aiwf-vaadin-jooq/README.md +56 -0
- package/plugins/aiwf-vaadin-jooq/UPSTREAM.json +43 -0
- package/plugins/aiwf-vaadin-jooq/agents/uc-coverage.md +260 -0
- package/plugins/aiwf-vaadin-jooq/rules/mcp-servers.md +44 -0
- package/plugins/aiwf-vaadin-jooq/skills/browserless-test/SKILL.md +407 -0
- package/plugins/aiwf-vaadin-jooq/skills/browserless-test/references/UC001ManagePersonsTest.java +111 -0
- package/plugins/aiwf-vaadin-jooq/skills/coverage-check/SKILL.md +190 -0
- package/plugins/aiwf-vaadin-jooq/skills/flyway-migration/SKILL.md +70 -0
- package/plugins/aiwf-vaadin-jooq/skills/hilla-test/SKILL.md +350 -0
- package/plugins/aiwf-vaadin-jooq/skills/hilla-test/references/UC001ManagePersonsServiceTest.java +81 -0
- package/plugins/aiwf-vaadin-jooq/skills/hilla-test/references/UC001ManagePersonsViewTest.tsx +87 -0
- package/plugins/aiwf-vaadin-jooq/skills/implement/SKILL.md +196 -0
- package/plugins/aiwf-vaadin-jooq/skills/implement-hilla/SKILL.md +216 -0
- package/plugins/aiwf-vaadin-jooq/skills/karibu-test/SKILL.md +298 -0
- package/plugins/aiwf-vaadin-jooq/skills/karibu-test/references/UC001ManagePersonsTest.java +93 -0
- package/plugins/aiwf-vaadin-jooq/skills/playwright-test/SKILL.md +237 -0
- package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/ExampleViewIT.java +143 -0
- package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/TC001CustomerOnboardingIT.java +144 -0
- package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/dramafinder-api.md +190 -0
- package/scripts/check-dependencies.js +26 -96
- package/scripts/install-spec-skills.mjs +126 -0
- package/scripts/validate-spec-plugin.mjs +145 -0
- package/src/cli/spec-cli.js +292 -0
- package/src/lib/spec-workflow.js +982 -0
- package/docs/ADR_MANAGEMENT_GUIDE.ko.md +0 -602
- package/docs/ADR_MANAGEMENT_GUIDE.md +0 -602
- package/docs/AI-WORKFLOW.ko.md +0 -299
- package/docs/AI-WORKFLOW.md +0 -401
- package/docs/API_REFERENCE_FULL.ko.md +0 -1135
- package/docs/API_REFERENCE_FULL.md +0 -1135
- package/docs/ARCHITECTURE.ko.md +0 -314
- package/docs/ARCHITECTURE.md +0 -314
- package/docs/CLI_USAGE_GUIDE.ko.md +0 -634
- package/docs/CLI_USAGE_GUIDE.md +0 -640
- package/docs/CODE_CLEANUP_GUIDE.ko.md +0 -415
- package/docs/CODE_CLEANUP_GUIDE.md +0 -415
- package/docs/COMMANDS_GUIDE.ko.md +0 -1037
- package/docs/COMMANDS_GUIDE.md +0 -1037
- package/docs/CONTRIBUTING.ko.md +0 -408
- package/docs/CONTRIBUTING.md +0 -408
- package/docs/DEVELOPMENT_GUIDE.ko.md +0 -440
- package/docs/DEVELOPMENT_GUIDE.md +0 -727
- package/docs/EXAMPLES.ko.md +0 -695
- package/docs/EXAMPLES.md +0 -693
- package/docs/GETTING_STARTED.ko.md +0 -219
- package/docs/GETTING_STARTED.md +0 -476
- package/docs/MODULE_MANAGEMENT_GUIDE.ko.md +0 -289
- package/docs/MODULE_MANAGEMENT_GUIDE.md +0 -289
- package/docs/PERFORMANCE_ARCHITECTURE.md +0 -494
- package/docs/PERFORMANCE_GUIDELINES.ko.md +0 -388
- package/docs/PERFORMANCE_GUIDELINES.md +0 -553
- package/docs/PRD.ko.md +0 -148
- package/docs/PRD.md +0 -150
- package/docs/ROADMAP_v0.4.0.md +0 -286
- package/docs/STATE_MANAGEMENT_GUIDE.ko.md +0 -278
- package/docs/STATE_MANAGEMENT_GUIDE.md +0 -278
- package/docs/TROUBLESHOOTING.ko.md +0 -366
- package/docs/TROUBLESHOOTING.md +0 -722
- package/docs/VALIDATOR_API.ko.md +0 -324
- package/docs/VALIDATOR_API.md +0 -324
- package/docs/YOLO_SYSTEM_GUIDE.ko.md +0 -542
- package/docs/YOLO_SYSTEM_GUIDE.md +0 -542
- package/docs/designs/AI_PERSONA_SYSTEM_DESIGN.md +0 -516
- package/docs/designs/API_DOCUMENTATION.md +0 -932
- package/docs/designs/API_REFERENCE.md +0 -979
- package/docs/designs/Enhanced_Installation_Flow_Design.md +0 -498
- package/docs/designs/aiwf-metadata-system-prd.md +0 -127
- package/docs/designs/offline-template-cache.md +0 -323
- package/docs/designs/persona-aware-compression.md +0 -168
- package/docs/guides/ai-personas-guide-ko.md +0 -239
- package/docs/guides/ai-personas-guide.md +0 -239
- package/docs/guides/checkpoint-system-guide-ko.md +0 -356
- package/docs/guides/checkpoint-system-guide.md +0 -356
- package/docs/guides/context-compression-guide-ko.md +0 -313
- package/docs/guides/context-compression-guide.md +0 -313
- package/docs/guides/independent-sprint-guide-ko.md +0 -321
- package/docs/guides/independent-sprint-guide.md +0 -321
- package/rules/global/aiwf-code-style-guide.md +0 -30
- package/rules/global/aiwf-coding-principles.md +0 -33
- package/rules/global/aiwf-development-process.md +0 -41
- package/rules/global/aiwf-global-rules.md +0 -84
- package/rules/manual/aiwf-generate-plan-docs.md +0 -280
- package/scripts/run-integration-tests.js +0 -317
- package/scripts/update-file-lists.js +0 -267
- package/scripts/validate-commands.js +0 -254
- package/src/DEPENDENCY_MAP.md +0 -90
- package/src/cli/cache-cli.js +0 -459
- package/src/cli/checkpoint-cli.js +0 -417
- package/src/cli/index.js +0 -481
- package/src/cli/language-cli.js +0 -286
- package/src/cli/sprint-cli.js +0 -287
- package/src/commands/ai-tool.js +0 -383
- package/src/commands/compress.js +0 -60
- package/src/commands/create-project.js +0 -160
- package/src/commands/evaluate.js +0 -459
- package/src/commands/persona.js +0 -309
- package/src/commands/sprint-independent.js +0 -393
- package/src/commands/sprint-task.js +0 -262
- package/src/commands/state.js +0 -1164
- package/src/commands/token.js +0 -312
- package/src/commands/yolo-config.js +0 -502
- package/src/config/file-lists.js +0 -147
- package/src/config/yolo-config-template.yaml +0 -168
- package/src/lib/ai-persona-manager.js +0 -711
- package/src/lib/backup-manager.js +0 -271
- package/src/lib/cache-system.js +0 -332
- package/src/lib/context-engine.js +0 -568
- package/src/lib/file-downloader.js +0 -304
- package/src/lib/github-integration.js +0 -402
- package/src/lib/installer.js +0 -1066
- package/src/lib/memory-profiler.js +0 -471
- package/src/lib/metrics-collector.js +0 -885
- package/src/lib/offline-detector.js +0 -386
- package/src/lib/resource-loader-enhanced.js +0 -399
- package/src/lib/resource-loader.js +0 -250
- package/src/lib/resources/commands/ai-persona.js +0 -602
- package/src/lib/resources/commands/compress-context.js +0 -389
- package/src/lib/resources/commands/evaluate.js +0 -246
- package/src/lib/resources/commands/persona-context-apply.js +0 -562
- package/src/lib/resources/commands/token-tracking.js +0 -443
- package/src/lib/resources/config/commit-patterns.js +0 -103
- package/src/lib/resources/config/language.json +0 -6
- package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
- package/src/lib/resources/personas/analyst.json +0 -44
- package/src/lib/resources/personas/architect/best_practices.md +0 -136
- package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
- package/src/lib/resources/personas/architect.json +0 -44
- package/src/lib/resources/personas/backend/best_practices.md +0 -766
- package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
- package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
- package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
- package/src/lib/resources/personas/developer.json +0 -44
- package/src/lib/resources/personas/developer.md +0 -37
- package/src/lib/resources/personas/evaluation_criteria.json +0 -137
- package/src/lib/resources/personas/frontend/best_practices.md +0 -445
- package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
- package/src/lib/resources/personas/persona-index.json +0 -31
- package/src/lib/resources/personas/reviewer.json +0 -44
- package/src/lib/resources/personas/security/best_practices.md +0 -307
- package/src/lib/resources/personas/security/knowledge_base.md +0 -498
- package/src/lib/resources/personas/tester.json +0 -44
- package/src/lib/resources/templates/README.md +0 -78
- package/src/lib/resources/templates/api-server/config.json +0 -64
- package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
- package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
- package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
- package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
- package/src/lib/resources/templates/api-server/template/.env.example +0 -29
- package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
- package/src/lib/resources/templates/api-server/template/README.md +0 -171
- package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
- package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
- package/src/lib/resources/templates/api-server/template/package.json +0 -61
- package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
- package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
- package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
- package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
- package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
- package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
- package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
- package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
- package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
- package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
- package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
- package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
- package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
- package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
- package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
- package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
- package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
- package/src/lib/resources/templates/npm-library/config.json +0 -61
- package/src/lib/resources/templates/npm-library/template/README.md +0 -201
- package/src/lib/resources/templates/npm-library/template/package.json +0 -78
- package/src/lib/resources/templates/web-app/config.json +0 -53
- package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
- package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
- package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
- package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
- package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
- package/src/lib/resources/templates/web-app/template/README.md +0 -151
- package/src/lib/resources/templates/web-app/template/index.html +0 -14
- package/src/lib/resources/templates/web-app/template/package.json +0 -44
- package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
- package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
- package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
- package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
- package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
- package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
- package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
- package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
- package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
- package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
- package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
- package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
- package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
- package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
- package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
- package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
- package/src/lib/resources/utils/background-monitor.js +0 -223
- package/src/lib/resources/utils/compression-metrics.js +0 -1031
- package/src/lib/resources/utils/compression-strategies.js +0 -557
- package/src/lib/resources/utils/content-normalizer.js +0 -455
- package/src/lib/resources/utils/context-compressor.js +0 -583
- package/src/lib/resources/utils/context-rule-parser.js +0 -180
- package/src/lib/resources/utils/context-token-monitor.js +0 -463
- package/src/lib/resources/utils/context-update-manager.js +0 -502
- package/src/lib/resources/utils/git-utils.js +0 -220
- package/src/lib/resources/utils/importance-classifier.js +0 -645
- package/src/lib/resources/utils/information-filter.js +0 -710
- package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
- package/src/lib/resources/utils/prompt-injector.js +0 -242
- package/src/lib/resources/utils/simplified-evaluator.js +0 -119
- package/src/lib/resources/utils/text-summarizer.js +0 -492
- package/src/lib/resources/utils/token-counter.js +0 -177
- package/src/lib/resources/utils/token-monitor.js +0 -484
- package/src/lib/resources/utils/token-reporter.js +0 -452
- package/src/lib/resources/utils/token-storage.js +0 -433
- package/src/lib/resources/utils/token-tracker.js +0 -283
- package/src/lib/rollback-manager.js +0 -418
- package/src/lib/state/priority-calculator.js +0 -217
- package/src/lib/state/state-index.js +0 -155
- package/src/lib/state/task-scanner.js +0 -328
- package/src/lib/task-analyzer.js +0 -599
- package/src/lib/template-cache-system.js +0 -559
- package/src/lib/template-downloader.js +0 -467
- package/src/lib/template-version-manager.js +0 -491
- package/src/lib/token-optimizer.js +0 -517
- package/src/lib/validator.js +0 -376
- package/src/utils/checkpoint-manager.js +0 -435
- package/src/utils/engineering-guard.js +0 -399
- package/src/utils/language-utils.js +0 -331
- package/src/utils/messages.js +0 -166
- package/src/utils/paths.js +0 -112
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Entity Model
|
|
2
|
+
|
|
3
|
+
> Status: Draft
|
|
4
|
+
|
|
5
|
+
## Entity Relationship Diagram
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
erDiagram
|
|
9
|
+
SUBMITTER ||--o{ EXPENSE_REPORT : "submits"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### SUBMITTER
|
|
13
|
+
|
|
14
|
+
지출 내역을 제출하는 사람을 나타낸다.
|
|
15
|
+
|
|
16
|
+
| Attribute | Description | Data Type | Length/Precision | Validation Rules |
|
|
17
|
+
|-----------|--------------------|-----------|------------------|-----------------------|
|
|
18
|
+
| id | 제출자 고유 식별자 | Long | 19 | Primary Key, Sequence |
|
|
19
|
+
| name | 제출자 이름 | String | 100 | Not Null |
|
|
20
|
+
|
|
21
|
+
### EXPENSE_REPORT
|
|
22
|
+
|
|
23
|
+
제출된 지출 내역 한 건을 나타낸다.
|
|
24
|
+
|
|
25
|
+
| Attribute | Description | Data Type | Length/Precision | Validation Rules |
|
|
26
|
+
|--------------|------------------|-----------|------------------|-------------------------------------|
|
|
27
|
+
| id | 지출 내역 식별자 | Long | 19 | Primary Key, Sequence |
|
|
28
|
+
| amount | 제출 금액 | Decimal | 10,2 | Not Null, greater than 0 |
|
|
29
|
+
| description | 사용 내용 | String | 200 code points | Optional; BR-002 |
|
|
30
|
+
| submitted_at | 제출 시각 | DateTime | - | Not Null |
|
|
31
|
+
| submitter_id | 제출자 참조 | Long | 19 | Not Null, Foreign Key (SUBMITTER.id) |
|
|
32
|
+
|
|
33
|
+
**Constraints:** 지출 내역의 금액은 0보다 커야 한다. 사용 내용은 Unicode code point 200개 이하여야 하며 생략·null은 빈 문자열로 정규화한다 (UC-001 BR-002). 실제 DB와 업무 정책은 이번 서비스 파일럿에서 검증하지 않는다.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
> Status: Reviewed
|
|
4
|
+
|
|
5
|
+
| Term | Definition | Avoid |
|
|
6
|
+
|-----------|----------------------------------------------------------------|-----------|
|
|
7
|
+
| 제출자 | 지출 내역을 작성해 제출하는 사람. | 신청자 |
|
|
8
|
+
| 지출 내역 | 정산을 위해 제출하는 금액과 사용 내용의 묶음. | 경비 청구 |
|
|
9
|
+
| 승인자 | 제출된 지출 내역을 검토하고 승인 여부를 결정하는 사람. | |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# UC-001 서비스 파일럿 구현 계획
|
|
2
|
+
|
|
3
|
+
범위: 가상 지출 제출의 서비스 부분. 실제 로그인·UI·DB·업무 수용은 별도 미검증이다.
|
|
4
|
+
|
|
5
|
+
## 명세와 실행 검사의 연결
|
|
6
|
+
|
|
7
|
+
| Check ID | 명세 범위 | 실행 명령 | 입력 | 미검증 사항 |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| C-STRUCTURE | FR-001 / UC-001 / TC-001 / TC-002 / 문서 연결 | 저장소 core의 spec_lint.py --strict --no-baseline --format json | docs/ 전체 pin 대상 | 한국어 의미·업무 수용 |
|
|
10
|
+
| C-SERVICE | UC-001 BR-001/BR-002, 기본 흐름의 기록·접수번호, A1 / A2 / A3, TC-001/TC-002 서비스 부분 | node --test tests/expense.test.mjs | src/expense.mjs, tests/expense.test.mjs | UI·계정·DB·동시성 |
|
|
11
|
+
| C-UI | UC-001 화면·접수표시 / TC-001/TC-002 전체 흐름 | 실제 앱 미지정 | 아직 없음 | not_run: UI와 인증 앱 없음 |
|
|
12
|
+
| C-HUMAN | 명세 의미·업무 수용 | 실제 사람의 packet 검토 | 해당 명세·packet·코드 | not_run: 실제 검토자 기록 없음 |
|
|
13
|
+
|
|
14
|
+
## 변경·검증 원칙
|
|
15
|
+
|
|
16
|
+
BR-002 검사 이름은 ASCII/astral Unicode의 200/201 경계, 숫자·배열·객체 타입 거부, 생략·null·빈 문자열 정규화와 TC-002의 201→200 수정 흐름을 식별한다. 기존 기록이 있는 상태에서 잘못된 입력이 기록을 바꾸지 않는지 검증한다. TC-002의 화면 메시지와 로그인은 C-UI에 남긴다.
|
|
17
|
+
|
|
18
|
+
명세·매핑·명령 변경은 pin drift로 확인한다. 코드·테스트의 bytes hash는 실행 기록에서 별도로 남기며 current CLI가 이를 검증한다고 주장하지 않는다. 새로운 명세에서 과거 성공 로그를 사용하지 않고 해당 단계의 명령을 다시 실행한다.
|
|
19
|
+
|
|
20
|
+
이 파일은 pin에 포함된 검토 문서다. 현재 CLI는 표에 있는 명령을 자동 실행하지 않는다. 실패와 not_run을 보존하고 packet은 awaiting_review로 유지한다.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Requirements
|
|
2
|
+
|
|
3
|
+
> Status: Reviewed
|
|
4
|
+
|
|
5
|
+
## Functional Requirements
|
|
6
|
+
|
|
7
|
+
| ID | Title | User Story | Priority | Status |
|
|
8
|
+
|--------|----------------|-----------------------------------------------------------------------------|----------|--------|
|
|
9
|
+
| FR-001 | 지출 내역 제출 | As a 제출자, I want 지출 내역을 제출하기 so that 승인자가 검토할 수 있다. | High | Open |
|
|
10
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Test Case: 지출 내역 제출
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**ID:** TC-001
|
|
6
|
+
**Goal:** 제출자가 지출 내역을 제출하고 접수 번호를 받는 흐름을 끝까지 확인한다.
|
|
7
|
+
**Priority:** High
|
|
8
|
+
**Status:** Reviewed
|
|
9
|
+
|
|
10
|
+
## Roles
|
|
11
|
+
|
|
12
|
+
- 제출자 (지출 금액과 사용 내용을 입력하고 제출한다)
|
|
13
|
+
|
|
14
|
+
## Preconditions
|
|
15
|
+
|
|
16
|
+
- 제출자 계정이 준비되어 있다 (테스트 데이터 시드)
|
|
17
|
+
|
|
18
|
+
## Flow
|
|
19
|
+
|
|
20
|
+
| Step | Name | Description | Test Data | Use Case |
|
|
21
|
+
|------|------|-------------|-----------|----------|
|
|
22
|
+
| 1 | 제출 시작 | 제출자가 지출 내역 제출을 시작한다 | - | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
23
|
+
| 2 | 잘못된 금액 입력 | 제출자가 금액과 사용 내용을 입력한다 | -100, 팀 회식 | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
24
|
+
| 3 | 오류 확인 | 금액 오류 메시지가 표시되고 제출된 내역이 없음을 확인한다 | - | - |
|
|
25
|
+
| 4 | 금액 수정 | 제출자가 금액을 수정한다 | 12000 | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
26
|
+
| 5 | 제출 확정 | 제출자가 제출을 확정한다 | - | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
27
|
+
| 6 | 접수 확인 | 접수 번호가 표시되는지 확인한다 | - | - |
|
|
28
|
+
|
|
29
|
+
## Validation
|
|
30
|
+
|
|
31
|
+
1. **접수 상태**: 최종 지출 내역이 제출 상태로 표시된다.
|
|
32
|
+
2. **금액 보존**: 기록된 금액이 12000으로 표시된다.
|
|
33
|
+
|
|
34
|
+
## Postconditions
|
|
35
|
+
|
|
36
|
+
- 지출 내역 1건이 제출 상태로 남는다 (금액 12000, 사용 내용 팀 회식).
|
|
37
|
+
- 접수 번호가 기록된다.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Test Case: 사용 내용 길이 수정 후 제출
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**ID:** TC-002
|
|
6
|
+
**Goal:** 사용 내용 길이 오류 후 수정하여 접수하는 UC-001 BR-002/A3 흐름을 확인한다.
|
|
7
|
+
**Priority:** High
|
|
8
|
+
**Status:** Draft
|
|
9
|
+
|
|
10
|
+
## Roles
|
|
11
|
+
|
|
12
|
+
- 제출자 (사용 내용을 수정하고 제출한다)
|
|
13
|
+
|
|
14
|
+
## Preconditions
|
|
15
|
+
|
|
16
|
+
- 제출자 계정이 준비되어 있다 (UI는 이번 파일럿에서 미실행)
|
|
17
|
+
- 기존 지출 내역 1건이 저장되어 있다
|
|
18
|
+
|
|
19
|
+
## Flow
|
|
20
|
+
|
|
21
|
+
| Step | Name | Description | Test Data | Use Case |
|
|
22
|
+
|------|------|-------------|-----------|----------|
|
|
23
|
+
| 1 | 제출 시작 | 제출자가 지출 내역 제출을 시작한다 | - | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
24
|
+
| 2 | 길이 초과 입력 | 제출자가 금액과 사용 내용을 입력한다 | 12000, a 201개 | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
25
|
+
| 3 | 오류 확인 | 사용 내용 길이 오류와 기존 기록 보존을 확인한다 | - | - |
|
|
26
|
+
| 4 | 사용 내용 수정 | 제출자가 사용 내용을 수정한다 | a 200개 | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
27
|
+
| 5 | 제출 확정 | 제출자가 제출을 확정한다 | - | [UC-001](../use_cases/UC-001-submit-expense.md) |
|
|
28
|
+
| 6 | 접수 확인 | 새 접수 번호와 최종 내용을 확인한다 | - | - |
|
|
29
|
+
|
|
30
|
+
## Validation
|
|
31
|
+
|
|
32
|
+
1. **길이 경계**: ASCII 및 astral Unicode 각각 200 code points는 저장되고 201은 기록 전에 거부된다.
|
|
33
|
+
2. **타입·선택 입력**: 숫자·배열·객체는 거부되고 생략·null·빈 문자열은 빈 문자열로 기록된다.
|
|
34
|
+
3. **기존 기록 보존**: 모든 거부 후 이전 기록은 변경되지 않는다.
|
|
35
|
+
4. **수정 접수**: 사용 내용을 201에서 200으로 수정한 뒤 새 접수 번호로 저장된다.
|
|
36
|
+
|
|
37
|
+
## Postconditions
|
|
38
|
+
|
|
39
|
+
- 이전 지출 내역 1건과 새 제출 1건이 남는다.
|
|
40
|
+
- 새 내용은 a 200개이며 새 접수 번호가 기록된다.
|
|
41
|
+
|
|
42
|
+
서비스 검사는 저장·거부·수정만 다룬다. 로그인·화면·오류 표시·접수 화면은 미검증이다.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Use Case: 지출 내역 제출
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**Use Case ID:** UC-001
|
|
6
|
+
**Use Case Name:** 지출 내역 제출
|
|
7
|
+
**Primary Actor:** 제출자
|
|
8
|
+
**Goal:** 제출자가 지출 내역을 제출하여 승인자가 검토할 수 있게 한다.
|
|
9
|
+
**Trigger:** 제출자가 지출 내역 제출을 요청한다.
|
|
10
|
+
**Status:** Draft
|
|
11
|
+
|
|
12
|
+
**Requirements:** [FR-001](../requirements.md)
|
|
13
|
+
|
|
14
|
+
## Preconditions
|
|
15
|
+
|
|
16
|
+
- 제출자가 시스템에 로그인되어 있다
|
|
17
|
+
- 제출할 지출 내역의 금액과 사용 내용을 알고 있다
|
|
18
|
+
|
|
19
|
+
## Main Success Scenario
|
|
20
|
+
|
|
21
|
+
1. 제출자가 지출 내역 제출을 시작한다.
|
|
22
|
+
2. 시스템이 지출 내역 입력 화면을 표시한다.
|
|
23
|
+
3. 제출자가 지출 금액과 사용 내용을 입력한다.
|
|
24
|
+
4. 시스템이 입력한 금액이 0보다 크고 사용 내용이 BR-002 조건을 만족하는지 확인한다.
|
|
25
|
+
5. 제출자가 제출을 확정한다.
|
|
26
|
+
6. 시스템이 지출 내역을 제출 상태로 기록하고 접수 번호를 표시한다.
|
|
27
|
+
|
|
28
|
+
## Alternative Flows
|
|
29
|
+
|
|
30
|
+
### A1: 유효하지 않은 금액
|
|
31
|
+
|
|
32
|
+
**Trigger:** 입력한 금액이 0 이하이다 (step 4)
|
|
33
|
+
**Flow:**
|
|
34
|
+
|
|
35
|
+
1. 시스템이 금액은 0보다 커야 한다는 메시지를 표시한다.
|
|
36
|
+
2. 제출자가 금액을 수정한다.
|
|
37
|
+
3. Use case continues at step 4.
|
|
38
|
+
|
|
39
|
+
### A2: 제출 처리 실패
|
|
40
|
+
|
|
41
|
+
**Trigger:** 시스템이 지출 내역을 기록할 수 없다 (step 6)
|
|
42
|
+
**Flow:**
|
|
43
|
+
|
|
44
|
+
1. 시스템이 제출을 완료하지 못했음을 알린다.
|
|
45
|
+
2. Use case ends.
|
|
46
|
+
|
|
47
|
+
### A3: 유효하지 않은 사용 내용
|
|
48
|
+
|
|
49
|
+
**Trigger:** 사용 내용이 문자열이 아니거나 Unicode code point 200개를 초과한다 (step 4)
|
|
50
|
+
**Flow:**
|
|
51
|
+
|
|
52
|
+
1. 시스템이 사용 내용의 타입 또는 길이 오류를 알리고 새 기록을 만들지 않는다.
|
|
53
|
+
2. 제출자가 사용 내용을 수정한다.
|
|
54
|
+
3. Use case continues at step 4.
|
|
55
|
+
|
|
56
|
+
## Postconditions
|
|
57
|
+
|
|
58
|
+
### Success Postconditions
|
|
59
|
+
|
|
60
|
+
- 지출 내역이 제출 상태로 기록되어 있다
|
|
61
|
+
- 제출자에게 접수 번호가 부여되어 있다
|
|
62
|
+
|
|
63
|
+
### Failure Postconditions
|
|
64
|
+
|
|
65
|
+
- 지출 내역이 제출 상태로 기록되지 않는다
|
|
66
|
+
- 기존에 기록된 지출 내역은 변경되지 않는다
|
|
67
|
+
|
|
68
|
+
## Business Rules
|
|
69
|
+
|
|
70
|
+
### BR-001: 금액 조건
|
|
71
|
+
|
|
72
|
+
제출하는 지출 금액은 0보다 커야 한다.
|
|
73
|
+
|
|
74
|
+
### BR-002: 사용 내용 조건
|
|
75
|
+
|
|
76
|
+
사용 내용은 선택 입력이다. 생략·null·빈 문자열은 빈 문자열로 기록한다. 그 밖의 값은 문자열이어야 하고, Unicode code point 기준 200개 이하여야 한다. UTF-16 code unit 수나 사용자 인식 글자 단위로 세지 않는다. 초과 또는 타입 오류는 기록 전에 거부하며 기존 기록을 보존한다. 이 조건은 로컬 예제 파일럿의 결정이고 실제 업무 정책은 미검토다.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Vision
|
|
2
|
+
|
|
3
|
+
> Status: Reviewed
|
|
4
|
+
|
|
5
|
+
## Product
|
|
6
|
+
|
|
7
|
+
지출 정산 시스템
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
팀 구성원이 지출 내역을 구두나 메신저로 보고하면 승인자가 금액과 사용 내용을 다시 확인해야 하므로 누락과 착오가 생긴다.
|
|
12
|
+
|
|
13
|
+
## Outcome
|
|
14
|
+
|
|
15
|
+
제출자가 지출 내역을 제출하면 접수 번호를 받고, 승인자가 검토할 수 있는 상태가 된다.
|
|
16
|
+
|
|
17
|
+
## Non-Goals
|
|
18
|
+
|
|
19
|
+
- 지출 승인과 반려 결정
|
|
20
|
+
- 회계 시스템으로의 자동 전기
|
|
21
|
+
- 지출 증빙 이미지의 자동 인식
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Process-local persistence for the bounded UC-001 smoke. */
|
|
2
|
+
export class InMemoryExpenseStore {
|
|
3
|
+
#records = [];
|
|
4
|
+
#failNext = false;
|
|
5
|
+
|
|
6
|
+
failNextWrite() {
|
|
7
|
+
this.#failNext = true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
insert(expense) {
|
|
11
|
+
// UC-001 A2: fail before mutation, preserving every earlier record.
|
|
12
|
+
if (this.#failNext) {
|
|
13
|
+
this.#failNext = false;
|
|
14
|
+
throw new Error('Expense persistence failed');
|
|
15
|
+
}
|
|
16
|
+
const record = structuredClone({
|
|
17
|
+
...expense,
|
|
18
|
+
receiptId: String(this.#records.length + 1),
|
|
19
|
+
});
|
|
20
|
+
this.#records.push(record);
|
|
21
|
+
return structuredClone(record);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
list() {
|
|
25
|
+
return structuredClone(this.#records);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function submitExpense(store, { amount, description = '' }) {
|
|
30
|
+
// UC-001 BR-001 / A1: no coercion or non-finite monetary amounts.
|
|
31
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
32
|
+
throw new RangeError('Amount must be a positive finite number');
|
|
33
|
+
}
|
|
34
|
+
// Pilot UC-001 BR-002 / A3: validate before any store mutation.
|
|
35
|
+
const normalizedDescription = description ?? '';
|
|
36
|
+
if (typeof normalizedDescription !== 'string') {
|
|
37
|
+
throw new TypeError('Description must be a string');
|
|
38
|
+
}
|
|
39
|
+
if (Array.from(normalizedDescription).length > 200) {
|
|
40
|
+
throw new RangeError('Description must be at most 200 Unicode code points');
|
|
41
|
+
}
|
|
42
|
+
return store.insert({
|
|
43
|
+
amount,
|
|
44
|
+
description: normalizedDescription,
|
|
45
|
+
status: 'submitted',
|
|
46
|
+
submitted_at: new Date().toISOString(),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { InMemoryExpenseStore, submitExpense } from '../src/expense.mjs';
|
|
4
|
+
|
|
5
|
+
test('UC-001 success persists amount, description, submitted state and receipt', () => {
|
|
6
|
+
const store = new InMemoryExpenseStore();
|
|
7
|
+
const first = submitExpense(store, { amount: 12000, description: '팀 회식' });
|
|
8
|
+
assert.equal(first.amount, 12000);
|
|
9
|
+
assert.equal(first.description, '팀 회식');
|
|
10
|
+
assert.equal(first.status, 'submitted');
|
|
11
|
+
assert.match(first.receiptId, /^\d+$/);
|
|
12
|
+
assert.ok(Number.isFinite(Date.parse(first.submitted_at)));
|
|
13
|
+
assert.deepEqual(store.list(), [first]);
|
|
14
|
+
const second = submitExpense(store, { amount: 0.01 });
|
|
15
|
+
assert.notEqual(second.receiptId, first.receiptId);
|
|
16
|
+
assert.equal(store.list().length, 2);
|
|
17
|
+
first.amount = 1;
|
|
18
|
+
const snapshot = store.list();
|
|
19
|
+
snapshot[0].description = 'changed';
|
|
20
|
+
snapshot.pop();
|
|
21
|
+
assert.equal(store.list()[0].amount, 12000);
|
|
22
|
+
assert.equal(store.list()[0].description, '팀 회식');
|
|
23
|
+
assert.equal(store.list().length, 2);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
for (const amount of [0, -1, -100, NaN, Infinity, -Infinity, '12000', null, undefined]) {
|
|
27
|
+
test(`UC-001 BR-001/A1 rejects ${String(amount)} without changing prior state`, () => {
|
|
28
|
+
const store = new InMemoryExpenseStore();
|
|
29
|
+
submitExpense(store, { amount: 25, description: 'earlier' });
|
|
30
|
+
const before = store.list();
|
|
31
|
+
assert.throws(() => submitExpense(store, { amount }), {
|
|
32
|
+
name: 'RangeError', message: 'Amount must be a positive finite number',
|
|
33
|
+
});
|
|
34
|
+
assert.deepEqual(store.list(), before);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
test('TC-001 service slice permits correction from -100 to 12000', () => {
|
|
39
|
+
const store = new InMemoryExpenseStore();
|
|
40
|
+
assert.throws(() => submitExpense(store, { amount: -100, description: '팀 회식' }), RangeError);
|
|
41
|
+
assert.deepEqual(store.list(), []);
|
|
42
|
+
const record = submitExpense(store, { amount: 12000, description: '팀 회식' });
|
|
43
|
+
assert.deepEqual(store.list(), [record]);
|
|
44
|
+
assert.equal(record.amount, 12000);
|
|
45
|
+
assert.equal(record.description, '팀 회식');
|
|
46
|
+
assert.equal(record.status, 'submitted');
|
|
47
|
+
assert.ok(record.receiptId);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('UC-001 A2 storage failure preserves earlier records and permits recovery', () => {
|
|
51
|
+
const store = new InMemoryExpenseStore();
|
|
52
|
+
const first = submitExpense(store, { amount: 100, description: 'earlier' });
|
|
53
|
+
const before = store.list();
|
|
54
|
+
store.failNextWrite();
|
|
55
|
+
assert.throws(() => submitExpense(store, { amount: 200, description: 'failed' }),
|
|
56
|
+
{ message: 'Expense persistence failed' });
|
|
57
|
+
assert.deepEqual(store.list(), before);
|
|
58
|
+
const recovered = submitExpense(store, { amount: 300, description: 'recovered' });
|
|
59
|
+
assert.notEqual(recovered.receiptId, first.receiptId);
|
|
60
|
+
assert.deepEqual(store.list(), [first, recovered]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
for (const [label, unit] of [['ASCII', 'a'], ['astral Unicode', '😀']]) {
|
|
64
|
+
test(`UC-001 BR-002 accepts 200 ${label} code points`, () => {
|
|
65
|
+
const store = new InMemoryExpenseStore();
|
|
66
|
+
const description = unit.repeat(200);
|
|
67
|
+
const record = submitExpense(store, { amount: 12000, description });
|
|
68
|
+
assert.equal(record.description, description);
|
|
69
|
+
assert.equal(Array.from(record.description).length, 200);
|
|
70
|
+
assert.deepEqual(store.list(), [record]);
|
|
71
|
+
});
|
|
72
|
+
test(`UC-001 BR-002/A3 rejects 201 ${label} code points without mutation`, () => {
|
|
73
|
+
const store = new InMemoryExpenseStore();
|
|
74
|
+
submitExpense(store, { amount: 25, description: 'earlier' });
|
|
75
|
+
const before = store.list();
|
|
76
|
+
assert.throws(() => submitExpense(store, { amount: 12000, description: unit.repeat(201) }), {
|
|
77
|
+
name: 'RangeError', message: 'Description must be at most 200 Unicode code points',
|
|
78
|
+
});
|
|
79
|
+
assert.deepEqual(store.list(), before);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const [label, description] of [['number', 42], ['array', []], ['object', {}]]) {
|
|
84
|
+
test(`UC-001 BR-002/A3 rejects ${label} description without mutation`, () => {
|
|
85
|
+
const store = new InMemoryExpenseStore();
|
|
86
|
+
submitExpense(store, { amount: 25, description: 'earlier' });
|
|
87
|
+
const before = store.list();
|
|
88
|
+
assert.throws(() => submitExpense(store, { amount: 12000, description }), {
|
|
89
|
+
name: 'TypeError', message: 'Description must be a string',
|
|
90
|
+
});
|
|
91
|
+
assert.deepEqual(store.list(), before);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const [label, description] of [['omitted', undefined], ['null', null], ['empty', '']]) {
|
|
96
|
+
test(`UC-001 BR-002 normalizes ${label} optional description to empty string`, () => {
|
|
97
|
+
const store = new InMemoryExpenseStore();
|
|
98
|
+
const input = { amount: 12000 };
|
|
99
|
+
if (label !== 'omitted') input.description = description;
|
|
100
|
+
const record = submitExpense(store, input);
|
|
101
|
+
assert.equal(record.description, '');
|
|
102
|
+
assert.deepEqual(store.list(), [record]);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
test('TC-002 service slice corrects 201 to 200 and preserves earlier records', () => {
|
|
107
|
+
const store = new InMemoryExpenseStore();
|
|
108
|
+
const first = submitExpense(store, { amount: 25, description: 'earlier' });
|
|
109
|
+
const before = store.list();
|
|
110
|
+
assert.throws(() => submitExpense(store, { amount: 12000, description: 'a'.repeat(201) }), RangeError);
|
|
111
|
+
assert.deepEqual(store.list(), before);
|
|
112
|
+
const corrected = submitExpense(store, { amount: 12000, description: 'a'.repeat(200) });
|
|
113
|
+
assert.equal(corrected.description, 'a'.repeat(200));
|
|
114
|
+
assert.notEqual(corrected.receiptId, first.receiptId);
|
|
115
|
+
assert.deepEqual(store.list(), [first, corrected]);
|
|
116
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "local_example_service_slice",
|
|
3
|
+
"base_revision": "fcf5ebc24bcd5e49148290a65ac6e1a5c4b22ba6",
|
|
4
|
+
"original_project_root": "/private/tmp/aiwf-uc001-pilot-l07zou4o/project",
|
|
5
|
+
"archive_project_root": "/Users/moonklabs/workspace-plugin/aiwf/docs/modernization/evidence/local-pilot-20261003/project",
|
|
6
|
+
"human_review": "not_recorded",
|
|
7
|
+
"human_active_time": "not_measured",
|
|
8
|
+
"reviewed_plan_sha256": "426d38f8d52001678083979ca7418c64c6d0b780fa8ef504aec1d6aa5c6b7ab8",
|
|
9
|
+
"node": "v22.23.1",
|
|
10
|
+
"python": "Python 3.14.8",
|
|
11
|
+
"final_input_sha256": {
|
|
12
|
+
"docs/entity_model.md": "aeb25fc9017964259e74f99220b87efe13b722bffa716b1b12f3b82f9c7ee5d8",
|
|
13
|
+
"docs/glossary.md": "093fc46be4b64534e670c046d935fce2287246190390d119f4c2edf43b7aedd9",
|
|
14
|
+
"docs/plans/UC-001.md": "e54f99e9d9cea07c2f74979f2bd2b0295d451eaf713ade031f76630d8a453491",
|
|
15
|
+
"docs/requirements.md": "d6190c0cfe5b43cd1fa7ba46fb252a558cc2854b0a5523cce7c2cf34db2c5254",
|
|
16
|
+
"docs/test_cases/TC-001-submit-expense.md": "f47b50f116ac8af187daf8915382c3a7e084d0110840b8b2cd0413f5d9a5d3b2",
|
|
17
|
+
"docs/test_cases/TC-002-description-limit.md": "516fa1b0252d8870fe773bcd56b89b1086f45a7f792a573635395e2a89780745",
|
|
18
|
+
"docs/use_cases/UC-001-submit-expense.md": "f41984bc93f5d352f92bc3f62a1bc6d1dae3d5e931ed5b7ce4d44506afbcf93c",
|
|
19
|
+
"docs/use_cases.puml": "b693ab2ddf7896b404a5193acd1fe65c3b4e0bb768df56a54360dc0f8c3a412d",
|
|
20
|
+
"docs/vision.md": "52fabfa494c1419bc1045f3404e26478a523a52c0f9910c40ac0199a7a9455fd",
|
|
21
|
+
"src/expense.mjs": "8f434f4614809a9ec3c478235232bc0a14b586fab6e7a6c4467e91d7040c0669",
|
|
22
|
+
"tests/expense.test.mjs": "90b7203d0933c09b63d3d2ba1e302bb45eef8932f2d54837d27194e82a9ad439"
|
|
23
|
+
},
|
|
24
|
+
"tool_sha256_at_archive": {
|
|
25
|
+
"src/cli/spec-cli.js": "52696829099edd56650e7966c14519dd12d09f7368077d63b28e10ad0e905a5c",
|
|
26
|
+
"src/lib/spec-workflow.js": "1c23a091ac0ed32812adb2f5c889d08fdf8427583f734e8b22eddb1895fa709b",
|
|
27
|
+
"plugins/aiwf-core/skills/spec-review/scripts/spec_lint.py": "8a70d669f165870045c2174c47073cd3496f9da40de658d9695e876e6620f031",
|
|
28
|
+
"plugins/aiwf-core/skills/use-case-spec/scripts/validate_use_case.py": "3a4cee5406639eb5406d8ec01bde4d7488ff31e3b8500566011a884bb6622be9",
|
|
29
|
+
"plugins/aiwf-core/skills/test-case/scripts/bpmn_paths.py": "8821d2fac8334219dda5271ab366d0f681a6a51545aa94bd462964c3598be8fb"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Claude 계획 리뷰 — 검증·실행 기록 계약
|
|
2
|
+
|
|
3
|
+
작성: 2026-10-03. 상태: **AI 리뷰 완료, 휴먼 리뷰 대기**.
|
|
4
|
+
|
|
5
|
+
[검토 대상 계획](../../CLI-PRODUCTIVITY.ko.md), [통합 판단](../../CLAUDE-PLAN-REVIEW-2026-10-03.ko.md).
|
|
6
|
+
|
|
7
|
+
- 실제 CLI: Claude Code `2.1.288`.
|
|
8
|
+
- 세션 ID: `cab3cadc-37d4-4ebb-a699-0d122c4c3baa`.
|
|
9
|
+
- 요청·관측 모델: `claude-sonnet-5-5` (`modelUsage` 확인).
|
|
10
|
+
- 요청 effort: `high`. 결과 JSON에 실제 적용 effort가 없어 관측 effort는 미확인.
|
|
11
|
+
- 검토 당시 계획 SHA256: `426d38f8d52001678083979ca7418c64c6d0b780fa8ef504aec1d6aa5c6b7ab8`.
|
|
12
|
+
- 실행 결과: exit 0, `subtype: success`, `is_error: false`, 권한 거부 0, stderr 0 bytes.
|
|
13
|
+
- 도구: `Glob, Grep, Read`. 원문 결과를 별도 수정 없이 아래에 옮겼다. 행 번호는 위 hash의 계획을 기준으로 한다.
|
|
14
|
+
- 셸·테스트 실행 및 파일 편집은 리뷰 세션에 제공하지 않았다. 모델 리뷰는 자동 테스트 통과나 휴먼 승인이 아니다.
|
|
15
|
+
|
|
16
|
+
아래는 최종 리뷰 답변이며, 프롬프트·전체 세션 JSON·실행 로그는 저장소 밖의 비공개 임시 경로에 유지한다.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# review-2 결과: 검증/실행 기록 계약 · 기존 코드 정합성 · 최소 구현 복잡성
|
|
21
|
+
|
|
22
|
+
## 결론: 조건부 적합
|
|
23
|
+
|
|
24
|
+
계획의 현황 진술은 코드와 맞습니다. 위험을 줄이는 방향도 타당합니다. 다만 "UC/BR/TC→check 매핑과 검사 정의의 위치·신뢰 경계"가 정해져 있지 않습니다. 이 항목은 `fresh` 판정과 opt-in runner 경계의 전제입니다. 또 두 번째 단계를 "하나의 기능 단위"로 묶은 범위(15, 93행)가 첫 구현으로는 큽니다. 아래 P1을 정하고 P2의 범위 축소를 반영하면 구현 착수에 적합합니다.
|
|
25
|
+
|
|
26
|
+
## 코드와 대조해 맞는 진술 (사실)
|
|
27
|
+
|
|
28
|
+
- 현재 명령은 `init/pin/check/packet` 4개입니다 (`src/cli/spec-cli.js:33-58`).
|
|
29
|
+
- evidence 입력은 top-level `checks/unverified`만, 검사별로는 `name/command/status/log`만 허용합니다. 그 외 필드는 `evidence_unknown_field`로 거부합니다 (`src/lib/spec-workflow.js:630-661`). 계획의 28행과 121행은 맞습니다.
|
|
30
|
+
- packet은 생성 시점에 `checkSpec`을 호출하고 로그를 읽습니다. `trust: 'reported_untrusted'`와 `acceptance: 'not_recorded'`를 기록합니다 (`spec-workflow.js:755-808`).
|
|
31
|
+
- 로그는 1 MiB 이하의 정확한 UTF-8만 허용합니다 (`spec-workflow.js:734-742`).
|
|
32
|
+
- 모든 구조 검사는 lint가 통합 실행합니다. 누락된 validator와 BPMN parser는 INFO로만 남습니다 (`spec_lint.py:358-364`, `538-544`). lint는 INFO만 있으면 exit 0을 반환합니다 (`spec_lint.py:1210-1212`).
|
|
33
|
+
- `--trace`는 항상 exit 0을 반환하고 lint를 실행하지 않습니다 (`spec_lint.py:1160-1168`).
|
|
34
|
+
- workflow가 이미 `spec_lint.py --strict --no-baseline`을 지시하므로 verify 설계와 일치합니다 (`plugins/aiwf-spec/skills/workflow/SKILL.md:28`).
|
|
35
|
+
|
|
36
|
+
## 지적
|
|
37
|
+
|
|
38
|
+
### P1. 검사 정의·매핑의 저장 위치와 신뢰 경계가 미정이다 (`CLI-PRODUCTIVITY.ko.md:97, 102, 111, 113`)
|
|
39
|
+
|
|
40
|
+
- **근거(사실):**
|
|
41
|
+
- pin은 `SPEC_DIRS`와 lint baseline만 추적합니다. 매핑이나 검사 정의 파일을 `docs/` 밖에 두면 바뀌어도 drift로 잡히지 않습니다 (`spec-workflow.js:27-39`).
|
|
42
|
+
- 계획은 "프로젝트가 명시적으로 정의한 검사 ID"를 실행한다고 쓰지만, 정의 파일의 위치·schema는 정하지 않았습니다.
|
|
43
|
+
- config hash는 receipt 기록 항목(102행)일 뿐, 실행 전 신뢰 확인에 쓰이지 않습니다.
|
|
44
|
+
- **영향(추론):** 저장소에 들어온 정의가 argv를 그대로 실행하게 됩니다. 정의가 바뀌어도 pin이 반응하지 않으면 UC/BR/TC→check 연결의 최신성(`fresh`)을 보장할 수 없습니다. dry-run만으로는 "누가 이 명령을 실행해도 된다고 승인했는가"가 남습니다.
|
|
45
|
+
- **최소 수정안:**
|
|
46
|
+
1. 정의 파일의 위치와 pin 포함 여부를 계획에서 결정합니다.
|
|
47
|
+
2. 정의 hash를 receipt에 기록하는 것과 별개로, runner는 실행 시점의 정의 hash를 사용자가 지정한 값과 대조하거나 `--yes` 같은 명시적 호출 입력을 요구합니다. 이 동작 자체가 "묵시 승인 금지" 경계가 됩니다.
|
|
48
|
+
3. UC/BR/TC ID 존재 검사는 새 파서를 만들지 않고 `spec_lint.py --trace --format json` 출력을 재사용합니다. 이 재사용이 가능한지는 trace JSON 스키마를 읽어 확인하지 못했습니다.
|
|
49
|
+
|
|
50
|
+
### P2. verify의 "전체 통과" 판정이 lint 출력 해석에 의존하는데 오류 분기가 빠졌다 (`:83-87`, `:134`)
|
|
51
|
+
|
|
52
|
+
- **근거(사실):**
|
|
53
|
+
- `load_sibling`은 모든 예외를 삼키고 `None`을 반환합니다 (`spec_lint.py:177-179`).
|
|
54
|
+
- INFO는 UC 파일이 있을 때(`check_structure`의 `if not specs: return`), 또는 BPMN 파일이 있을 때만 나옵니다. "로드 성공"의 신호는 INFO가 없다는 사실뿐입니다.
|
|
55
|
+
- Python 미설치나 `spawn ENOENT`, 버전 불일치, 미처리 예외는 계획에 분류가 없습니다. 미처리 예외도 exit 1이라 lint 오류 exit 1과 구분되지 않습니다.
|
|
56
|
+
- lint의 `--docs` 오류는 exit 2입니다 (`spec_lint.py:1155-1158`). CLI의 exit 2는 사용법 오류입니다 (`spec-cli.js:23`).
|
|
57
|
+
- **영향:** stdout JSON 파싱 성공 여부를 검증하지 않으면 실행 오류가 `lint failed`로, 최악에는 조용한 incomplete 누락으로 이어집니다.
|
|
58
|
+
- **최소 수정안:**
|
|
59
|
+
1. verify 결과 상태를 `lint_failed`, `tool_error`, `incomplete`, `drift`로 분리합니다. 이때 JSON의 summary 필드가 존재하는지로 판정합니다.
|
|
60
|
+
2. Python 자식 프로세스에 `-B`를 붙이고, lint 실행 전후 `computePinDigest`를 재계산해 읽기 중 변경도 알립니다. 현재 `load_sibling`은 이미 bytecode 쓰기를 막고 있어(`:171`) readonly 경계 자체는 구현 가능합니다. 다만 CLI 쪽에서도 강제하는 편이 안전합니다.
|
|
61
|
+
3. verify의 exit code 체계(0/1/2와 incomplete 처리)를 `--help`와 문서에 명시합니다 (`spec-cli.js:148`).
|
|
62
|
+
|
|
63
|
+
### P2. 첫 runner 범위가 과하다 (`:15, 93-109`)
|
|
64
|
+
|
|
65
|
+
- **근거(사실):**
|
|
66
|
+
- 한 단위에 포함된 항목은 다음과 같습니다. 선언 범위의 새 파일을 포함하는 입력 manifest, 제외 정책, 환경 allowlist, 3상태 `fresh/stale/unknown`, 중단 receipt, packet v2입니다.
|
|
67
|
+
- 현재 코드에는 glob 기능이 없고 spec 디렉터리를 수작업으로 순회합니다 (`spec-workflow.js:142-174`). `package.json`은 Node 20+를 선언하며 의존성이 없습니다 (`package.json:43-45`).
|
|
68
|
+
- **추론:** Node 20 내장 API로 선언 입력의 glob을 만드는 비용이 불확실합니다. 이 점은 확인하지 못했습니다.
|
|
69
|
+
- **최소 수정안(첫 구현):**
|
|
70
|
+
- 입력은 **명시적 파일 경로 목록의 sha256**으로 시작합니다. glob, 신규 파일 탐지, 환경 allowlist는 파일럿 후로 미룹니다. 환경 allowlist는 비밀값 위험과 비교 대상 정의가 모두 필요합니다.
|
|
71
|
+
- 상태는 receipt에 `outcome`(passed/failed/start_error/timeout/aborted/not_run), 비교 시 `fresh/stale`로 줄입니다. 선언 입력 hash를 읽지 못한 경우는 `stale`이 아니라 `unknown` 하나로만 둡니다.
|
|
72
|
+
- 지금 계획의 방향(범위 밖 의존성을 제외 목록으로 명시)은 유지하되, 선언은 사용자가 쓴 경로 목록으로 한정합니다.
|
|
73
|
+
|
|
74
|
+
### P2. 1 MiB 로그 정책이 runner의 완료 조건과 충돌할 수 있다 (`:117`)
|
|
75
|
+
|
|
76
|
+
- **근거(사실):** 계획은 "이 제한 안에서 완전한 로그를 수집"하라고 하고, 초과를 성공으로 남기지 않는다고 합니다. 이 제한은 packet이 로그 본문을 packet에 포함하기 때문입니다 (`spec-workflow.js:734, 743-748`).
|
|
77
|
+
- **영향(추론):** Gradle, Maven, Playwright 같은 검사는 1 MiB를 넘기기 쉽습니다. 그러면 정상 통과한 검사가 `incomplete`로 처리되어 runner가 쓸모없어질 수 있습니다. 계획은 이때의 동작을 정하지 않았습니다.
|
|
78
|
+
- **최소 수정안:** receipt의 로그 파일(전체, hash·bytes)과 packet에 포함되는 발췌를 분리합니다. 초과분은 truncated 표시로 자르거나, 초과 시 packet 생성은 거부하되 receipt에는 전체를 보존합니다. 어느 쪽이든 계획에서 하나를 정해야 합니다.
|
|
79
|
+
|
|
80
|
+
### P3. packet 버전 용어 불일치와 baseline 동작 미기재
|
|
81
|
+
|
|
82
|
+
- **근거(사실):** 실제 packet은 숫자 `schema_version: 1`이고 `schema` 문자열 필드는 없습니다 (`spec-workflow.js:785`). 반면 Sprintable 설계안은 `"schema": "aiwf.review_packet.v1"`을 씁니다 (`SPRINTABLE.ko.md:33`). 이 불일치는 packet v2를 정의할 때 소비자 호환 계약의 혼선이 됩니다.
|
|
83
|
+
- **근거(사실):** verify는 `--no-baseline`을 강제합니다. 이미 수용된 baseline이 있는 프로젝트는 영원히 exit 0이 안 될 수 있습니다. 계획에 이 동작의 명시가 없습니다.
|
|
84
|
+
- **최소 수정안:** packet v2 착수 시 식별자 방식을 하나로 정합니다. verify 문서에 "baseline 무시, 수용 항목은 findings로 계속 보고"를 한 줄 추가합니다.
|
|
85
|
+
|
|
86
|
+
## 유지할 강점
|
|
87
|
+
|
|
88
|
+
- `reported_untrusted`, `acceptance: not_recorded`, awaiting_review를 유지하고 packet exit 0과 runner exit 0의 의미를 분리했습니다 (127행).
|
|
89
|
+
- 파일럿 선행, 병렬·Sprintable·자동 선택을 미루는 우선순위와 측정 지표(수작업 시간, 누락·오래된 로그 재사용 건수)가 적절합니다.
|
|
90
|
+
- "sidecar 파일만으로 packet이 출처를 검증하지 않는다", "receipt는 변조 불가 자료가 아니다"라는 보장 한계를 이미 명시했습니다 (125행). 이 부분은 과장이 아닙니다.
|
|
91
|
+
- verify와 runner의 readonly/opt-in 분리는 구현 가능합니다. 현행 `checkSpec`은 읽기 전용이고, lint는 `--update-baseline` 없이는 쓰지 않습니다 (`spec_lint.py:1176-1180`).
|
|
92
|
+
|
|
93
|
+
## 이견 없음
|
|
94
|
+
|
|
95
|
+
- 계획의 "현재 CLI는 lint를 실행하지 않는다"와 "INFO만이면 exit 0"이라는 진술은 코드와 일치합니다.
|
|
96
|
+
- 문서 우선 원칙(원문·한글본·hash 동시 갱신, awaiting_review 유지)은 이 계획과 충돌하지 않습니다.
|
|
97
|
+
|
|
98
|
+
## 미확인·휴먼 결정
|
|
99
|
+
|
|
100
|
+
- **미확인:**
|
|
101
|
+
- Windows `.cmd` 실행과 프로세스 트리 종료, Node 20에서의 glob 대체 비용.
|
|
102
|
+
- `--trace --format json`이 UC/BR/TC 전체 연결을 담는지 (스키마 미확인).
|
|
103
|
+
- 계획의 수치(문서 70개, 검토 0개)와 문서 변경 후 hash·README·catalog 일관성은 이 세션 담당 밖이라 확인하지 않았습니다.
|
|
104
|
+
- 계획 13행의 선행 파일럿 필요성은 다른 세션의 평가 범위입니다.
|
|
105
|
+
- **휴먼 결정:**
|
|
106
|
+
1. 검사 정의 파일의 위치와 pin 포함 여부, 실행 전 신뢰 확인 방식 (P1).
|
|
107
|
+
2. 로그 1 MiB 초과 시 정책 (P2).
|
|
108
|
+
3. 첫 runner의 입력 선언 방식(명시 경로 목록)과 Node 20 하한 (140행의 별도 결정과 연결).
|
|
109
|
+
4. packet v2의 식별자 방식(P3).
|
|
110
|
+
|
|
111
|
+
## 수행 기록
|
|
112
|
+
|
|
113
|
+
- **파일 변경 없음.**
|
|
114
|
+
- **셸·테스트·검사 실행 없음.** `npm test`나 `docs:check`는 실행하지 않았고, 계획 170-175행의 통과 기록을 재현하지 않았습니다.
|
|
115
|
+
- 다른 세션 결과는 보지 않았습니다.
|
|
116
|
+
- **권한 거부 없음.**
|
|
117
|
+
- 읽은 파일:
|
|
118
|
+
- `AGENTS.md`, `docs/ko-skills/README.md`, `docs/modernization/CLI-PRODUCTIVITY.ko.md`, `docs/modernization/DIRECTION.ko.md`
|
|
119
|
+
- `src/lib/spec-workflow.js`, `src/cli/spec-cli.js`, `package.json`
|
|
120
|
+
- `spec_lint.py`(일부), workflow `SKILL.md`(일부), `SPRINTABLE.ko.md`(일부)
|
|
121
|
+
- `tests/spec-workflow/*.test.mjs`는 매칭 횟수만 확인했습니다. 본문은 읽지 않았습니다.
|
|
122
|
+
- 시스템 컨텍스트에 있던 `CLAUDE.md`의 내용은 따랐습니다.
|