sherpa-skill 2.0.6 → 2.0.7
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/.agents/plugins/marketplace.json +11 -0
- package/.agents/skills/sherpa/SKILL.md +161 -0
- package/.agents/skills/sherpa/commands/README.md +43 -0
- package/.agents/skills/sherpa/commands/manifest.json +589 -0
- package/.agents/skills/sherpa/commands/sherpa-research.md +147 -0
- package/.agents/skills/sherpa/core/commands/router.py +171 -0
- package/.agents/skills/sherpa/core/configuration/manager.py +504 -0
- package/.agents/skills/sherpa/core/ideas/engine.py +564 -0
- package/.agents/skills/sherpa/docs/commands/README.md +96 -0
- package/.agents/skills/sherpa/docs/configuration/runtime-verification.md +64 -0
- package/.agents/skills/sherpa/rules/demo-preparation-rules.md +543 -0
- package/.agents/skills/sherpa/rules/engineering-rules.md +221 -0
- package/.agents/skills/sherpa/rules/final-audit-rules.md +824 -0
- package/.agents/skills/sherpa/rules/implementation-rules.md +127 -0
- package/.agents/skills/sherpa/rules/judge-rules.md +443 -0
- package/.agents/skills/sherpa/rules/mentor-rules.md +109 -0
- package/.agents/skills/sherpa/rules/postmortem-rules.md +69 -0
- package/.agents/skills/sherpa/rules/presentation-rules.md +783 -0
- package/.agents/skills/sherpa/rules/red-team-rules.md +185 -0
- package/.agents/skills/sherpa/rules/research-rules.md +184 -0
- package/.agents/skills/sherpa/rules/score-optimization-rules.md +355 -0
- package/.agents/skills/sherpa/rules/scoring-rules.md +216 -0
- package/.agents/skills/sherpa/rules/submission-rules.md +41 -0
- package/.agents/skills/sherpa/rules/testing-security-rules.md +87 -0
- package/.agents/skills/sherpa/rules/ux-rules.md +89 -0
- package/.agents/skills/sherpa/src/config_manager.py +474 -0
- package/.agents/skills/sherpa/src/verification.py +458 -0
- package/.agents/skills/sherpa/templates/audit-finding.md +20 -0
- package/.agents/skills/sherpa/templates/claim-audit.md +15 -0
- package/.agents/skills/sherpa/templates/configuration/hackathon.json +21 -0
- package/.agents/skills/sherpa/templates/configuration/integrations.env.example +3 -0
- package/.agents/skills/sherpa/templates/configuration/project.env.example +12 -0
- package/.agents/skills/sherpa/templates/configuration/providers.env.example +4 -0
- package/.agents/skills/sherpa/templates/configuration/settings.json +22 -0
- package/.agents/skills/sherpa/templates/consistency-audit.md +17 -0
- package/.agents/skills/sherpa/templates/decision-log.md +18 -0
- package/.agents/skills/sherpa/templates/demo-checkpoint.md +42 -0
- package/.agents/skills/sherpa/templates/demo-evidence.md +32 -0
- package/.agents/skills/sherpa/templates/demo-finding.md +112 -0
- package/.agents/skills/sherpa/templates/demo-flow.md +52 -0
- package/.agents/skills/sherpa/templates/demo-plan.md +265 -0
- package/.agents/skills/sherpa/templates/demo-verification.md +57 -0
- package/.agents/skills/sherpa/templates/final-audit.md +387 -0
- package/.agents/skills/sherpa/templates/final-risk.md +17 -0
- package/.agents/skills/sherpa/templates/final-verification.md +57 -0
- package/.agents/skills/sherpa/templates/gap-analysis.md +113 -0
- package/.agents/skills/sherpa/templates/idea-comparison.md +129 -0
- package/.agents/skills/sherpa/templates/idea-evaluation.md +251 -0
- package/.agents/skills/sherpa/templates/implementation-plan.md +96 -0
- package/.agents/skills/sherpa/templates/implementation-task.md +57 -0
- package/.agents/skills/sherpa/templates/improvement-candidate.md +135 -0
- package/.agents/skills/sherpa/templates/improvement.md +18 -0
- package/.agents/skills/sherpa/templates/incident.md +20 -0
- package/.agents/skills/sherpa/templates/judge-criterion.md +41 -0
- package/.agents/skills/sherpa/templates/judge-question.md +41 -0
- package/.agents/skills/sherpa/templates/judge-session.md +125 -0
- package/.agents/skills/sherpa/templates/judge-simulation.md +264 -0
- package/.agents/skills/sherpa/templates/lesson.md +14 -0
- package/.agents/skills/sherpa/templates/postmortem.md +87 -0
- package/.agents/skills/sherpa/templates/presentation-evidence.md +33 -0
- package/.agents/skills/sherpa/templates/presentation-plan.md +349 -0
- package/.agents/skills/sherpa/templates/presentation-qna.md +29 -0
- package/.agents/skills/sherpa/templates/presentation-risk.md +42 -0
- package/.agents/skills/sherpa/templates/presentation-verification.md +57 -0
- package/.agents/skills/sherpa/templates/project-plan.md +242 -0
- package/.agents/skills/sherpa/templates/project-state.md +84 -0
- package/.agents/skills/sherpa/templates/red-team-finding.md +73 -0
- package/.agents/skills/sherpa/templates/red-team-review.md +105 -0
- package/.agents/skills/sherpa/templates/red-team-scenario.md +43 -0
- package/.agents/skills/sherpa/templates/red-team-verification.md +31 -0
- package/.agents/skills/sherpa/templates/repo-analysis.md +204 -0
- package/.agents/skills/sherpa/templates/requirement-audit.md +15 -0
- package/.agents/skills/sherpa/templates/research-comparison.md +124 -0
- package/.agents/skills/sherpa/templates/research-plan.md +93 -0
- package/.agents/skills/sherpa/templates/research-report.md +92 -0
- package/.agents/skills/sherpa/templates/research-source.md +77 -0
- package/.agents/skills/sherpa/templates/score-optimization-plan.md +197 -0
- package/.agents/skills/sherpa/templates/security-finding.md +45 -0
- package/.agents/skills/sherpa/templates/security-review.md +64 -0
- package/.agents/skills/sherpa/templates/slide-claim.md +47 -0
- package/.agents/skills/sherpa/templates/slide-plan.md +127 -0
- package/.agents/skills/sherpa/templates/submission-artifact.md +15 -0
- package/.agents/skills/sherpa/templates/submission-checklist.md +24 -0
- package/.agents/skills/sherpa/templates/submission-field.md +14 -0
- package/.agents/skills/sherpa/templates/submission-link.md +14 -0
- package/.agents/skills/sherpa/templates/submission-plan.md +31 -0
- package/.agents/skills/sherpa/templates/submission-readiness.md +18 -0
- package/.agents/skills/sherpa/templates/submission-requirement.md +12 -0
- package/.agents/skills/sherpa/templates/submission-risk.md +14 -0
- package/.agents/skills/sherpa/templates/submission-snapshot.md +20 -0
- package/.agents/skills/sherpa/templates/submission-verification.md +12 -0
- package/.agents/skills/sherpa/templates/test-plan.md +59 -0
- package/.agents/skills/sherpa/templates/test-result.md +46 -0
- package/.agents/skills/sherpa/templates/timeline.md +11 -0
- package/.agents/skills/sherpa/templates/ux-finding.md +56 -0
- package/.agents/skills/sherpa/templates/ux-flow.md +46 -0
- package/.agents/skills/sherpa/templates/ux-review.md +113 -0
- package/.agents/skills/sherpa/templates/ux-verification.md +32 -0
- package/.agents/skills/sherpa/workflows/configuration.md +23 -0
- package/.agents/skills/sherpa/workflows/demo-preparation.md +399 -0
- package/.agents/skills/sherpa/workflows/final-audit.md +713 -0
- package/.agents/skills/sherpa/workflows/idea-evaluation.md +239 -0
- package/.agents/skills/sherpa/workflows/idea-intelligence.md +69 -0
- package/.agents/skills/sherpa/workflows/implementation.md +42 -0
- package/.agents/skills/sherpa/workflows/init.md +102 -0
- package/.agents/skills/sherpa/workflows/judge-simulation.md +408 -0
- package/.agents/skills/sherpa/workflows/lifecycle.md +51 -0
- package/.agents/skills/sherpa/workflows/next.md +96 -0
- package/.agents/skills/sherpa/workflows/postmortem.md +76 -0
- package/.agents/skills/sherpa/workflows/presentation.md +522 -0
- package/.agents/skills/sherpa/workflows/project-planning.md +327 -0
- package/.agents/skills/sherpa/workflows/red-team.md +373 -0
- package/.agents/skills/sherpa/workflows/research.md +142 -0
- package/.agents/skills/sherpa/workflows/score-optimization.md +276 -0
- package/.agents/skills/sherpa/workflows/status.md +107 -0
- package/.agents/skills/sherpa/workflows/submission.md +46 -0
- package/.agents/skills/sherpa/workflows/testing-security.md +44 -0
- package/.agents/skills/sherpa/workflows/ux-review.md +59 -0
- package/.claude-plugin/marketplace.json +21 -0
- package/.claude-plugin/plugin.json +13 -0
- package/.codex-plugin/plugin.json +13 -0
- package/GEMINI.md +3 -0
- package/README.md +11 -7
- package/SKILL.md +161 -0
- package/distribution/cli/sherpa +1 -1
- package/gemini-extension.json +7 -0
- package/package.json +31 -3
- package/plugin.json +20 -0
- package/qwen-extension.json +6 -0
- package/skills/sherpa/SKILL.md +161 -0
- package/skills/sherpa/commands/README.md +43 -0
- package/skills/sherpa/commands/manifest.json +589 -0
- package/skills/sherpa/commands/sherpa-research.md +147 -0
- package/skills/sherpa/core/commands/router.py +171 -0
- package/skills/sherpa/core/configuration/manager.py +504 -0
- package/skills/sherpa/core/ideas/engine.py +564 -0
- package/skills/sherpa/docs/commands/README.md +96 -0
- package/skills/sherpa/docs/configuration/runtime-verification.md +64 -0
- package/skills/sherpa/rules/demo-preparation-rules.md +543 -0
- package/skills/sherpa/rules/engineering-rules.md +221 -0
- package/skills/sherpa/rules/final-audit-rules.md +824 -0
- package/skills/sherpa/rules/implementation-rules.md +127 -0
- package/skills/sherpa/rules/judge-rules.md +443 -0
- package/skills/sherpa/rules/mentor-rules.md +109 -0
- package/skills/sherpa/rules/postmortem-rules.md +69 -0
- package/skills/sherpa/rules/presentation-rules.md +783 -0
- package/skills/sherpa/rules/red-team-rules.md +185 -0
- package/skills/sherpa/rules/research-rules.md +184 -0
- package/skills/sherpa/rules/score-optimization-rules.md +355 -0
- package/skills/sherpa/rules/scoring-rules.md +216 -0
- package/skills/sherpa/rules/submission-rules.md +41 -0
- package/skills/sherpa/rules/testing-security-rules.md +87 -0
- package/skills/sherpa/rules/ux-rules.md +89 -0
- package/skills/sherpa/src/config_manager.py +474 -0
- package/skills/sherpa/src/verification.py +458 -0
- package/skills/sherpa/templates/audit-finding.md +20 -0
- package/skills/sherpa/templates/claim-audit.md +15 -0
- package/skills/sherpa/templates/configuration/hackathon.json +21 -0
- package/skills/sherpa/templates/configuration/integrations.env.example +3 -0
- package/skills/sherpa/templates/configuration/project.env.example +12 -0
- package/skills/sherpa/templates/configuration/providers.env.example +4 -0
- package/skills/sherpa/templates/configuration/settings.json +22 -0
- package/skills/sherpa/templates/consistency-audit.md +17 -0
- package/skills/sherpa/templates/decision-log.md +18 -0
- package/skills/sherpa/templates/demo-checkpoint.md +42 -0
- package/skills/sherpa/templates/demo-evidence.md +32 -0
- package/skills/sherpa/templates/demo-finding.md +112 -0
- package/skills/sherpa/templates/demo-flow.md +52 -0
- package/skills/sherpa/templates/demo-plan.md +265 -0
- package/skills/sherpa/templates/demo-verification.md +57 -0
- package/skills/sherpa/templates/final-audit.md +387 -0
- package/skills/sherpa/templates/final-risk.md +17 -0
- package/skills/sherpa/templates/final-verification.md +57 -0
- package/skills/sherpa/templates/gap-analysis.md +113 -0
- package/skills/sherpa/templates/idea-comparison.md +129 -0
- package/skills/sherpa/templates/idea-evaluation.md +251 -0
- package/skills/sherpa/templates/implementation-plan.md +96 -0
- package/skills/sherpa/templates/implementation-task.md +57 -0
- package/skills/sherpa/templates/improvement-candidate.md +135 -0
- package/skills/sherpa/templates/improvement.md +18 -0
- package/skills/sherpa/templates/incident.md +20 -0
- package/skills/sherpa/templates/judge-criterion.md +41 -0
- package/skills/sherpa/templates/judge-question.md +41 -0
- package/skills/sherpa/templates/judge-session.md +125 -0
- package/skills/sherpa/templates/judge-simulation.md +264 -0
- package/skills/sherpa/templates/lesson.md +14 -0
- package/skills/sherpa/templates/postmortem.md +87 -0
- package/skills/sherpa/templates/presentation-evidence.md +33 -0
- package/skills/sherpa/templates/presentation-plan.md +349 -0
- package/skills/sherpa/templates/presentation-qna.md +29 -0
- package/skills/sherpa/templates/presentation-risk.md +42 -0
- package/skills/sherpa/templates/presentation-verification.md +57 -0
- package/skills/sherpa/templates/project-plan.md +242 -0
- package/skills/sherpa/templates/project-state.md +84 -0
- package/skills/sherpa/templates/red-team-finding.md +73 -0
- package/skills/sherpa/templates/red-team-review.md +105 -0
- package/skills/sherpa/templates/red-team-scenario.md +43 -0
- package/skills/sherpa/templates/red-team-verification.md +31 -0
- package/skills/sherpa/templates/repo-analysis.md +204 -0
- package/skills/sherpa/templates/requirement-audit.md +15 -0
- package/skills/sherpa/templates/research-comparison.md +124 -0
- package/skills/sherpa/templates/research-plan.md +93 -0
- package/skills/sherpa/templates/research-report.md +92 -0
- package/skills/sherpa/templates/research-source.md +77 -0
- package/skills/sherpa/templates/score-optimization-plan.md +197 -0
- package/skills/sherpa/templates/security-finding.md +45 -0
- package/skills/sherpa/templates/security-review.md +64 -0
- package/skills/sherpa/templates/slide-claim.md +47 -0
- package/skills/sherpa/templates/slide-plan.md +127 -0
- package/skills/sherpa/templates/submission-artifact.md +15 -0
- package/skills/sherpa/templates/submission-checklist.md +24 -0
- package/skills/sherpa/templates/submission-field.md +14 -0
- package/skills/sherpa/templates/submission-link.md +14 -0
- package/skills/sherpa/templates/submission-plan.md +31 -0
- package/skills/sherpa/templates/submission-readiness.md +18 -0
- package/skills/sherpa/templates/submission-requirement.md +12 -0
- package/skills/sherpa/templates/submission-risk.md +14 -0
- package/skills/sherpa/templates/submission-snapshot.md +20 -0
- package/skills/sherpa/templates/submission-verification.md +12 -0
- package/skills/sherpa/templates/test-plan.md +59 -0
- package/skills/sherpa/templates/test-result.md +46 -0
- package/skills/sherpa/templates/timeline.md +11 -0
- package/skills/sherpa/templates/ux-finding.md +56 -0
- package/skills/sherpa/templates/ux-flow.md +46 -0
- package/skills/sherpa/templates/ux-review.md +113 -0
- package/skills/sherpa/templates/ux-verification.md +32 -0
- package/skills/sherpa/workflows/configuration.md +23 -0
- package/skills/sherpa/workflows/demo-preparation.md +399 -0
- package/skills/sherpa/workflows/final-audit.md +713 -0
- package/skills/sherpa/workflows/idea-evaluation.md +239 -0
- package/skills/sherpa/workflows/idea-intelligence.md +69 -0
- package/skills/sherpa/workflows/implementation.md +42 -0
- package/skills/sherpa/workflows/init.md +102 -0
- package/skills/sherpa/workflows/judge-simulation.md +408 -0
- package/skills/sherpa/workflows/lifecycle.md +51 -0
- package/skills/sherpa/workflows/next.md +96 -0
- package/skills/sherpa/workflows/postmortem.md +76 -0
- package/skills/sherpa/workflows/presentation.md +522 -0
- package/skills/sherpa/workflows/project-planning.md +327 -0
- package/skills/sherpa/workflows/red-team.md +373 -0
- package/skills/sherpa/workflows/research.md +142 -0
- package/skills/sherpa/workflows/score-optimization.md +276 -0
- package/skills/sherpa/workflows/status.md +107 -0
- package/skills/sherpa/workflows/submission.md +46 -0
- package/skills/sherpa/workflows/testing-security.md +44 -0
- package/skills/sherpa/workflows/ux-review.md +59 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# sherpa — Testing + Security Rules
|
|
2
|
+
|
|
3
|
+
Defines authoritative Phase 5 behavior. Phase 5 inspects the implemented project, creates test/security plans, executes applicable checks, records evidence, and evaluates quality. Phase 4 is a frozen dependency: never modify its rules, templates, or workflow. Phase 5 does not replace Phase 4 or silently modify application code or architecture.
|
|
4
|
+
|
|
5
|
+
## 1. Readiness and evidence first
|
|
6
|
+
|
|
7
|
+
Read `.sherpa/project-state.md`, the Phase 3 project plan, and `.sherpa/implementation-plan.md` before normal testing. Read artifacts at explicitly referenced stable paths when needed. Inspect the actual repository and test baseline before making claims.
|
|
8
|
+
|
|
9
|
+
- If `Implementation status = NOT_STARTED`, report `Testing blocked until implementation exists.` Do not run a normal project test campaign.
|
|
10
|
+
- If implementation status, selected idea, or required plans are missing/UNKNOWN, mark readiness `UNKNOWN` or `BLOCKED`; do not infer readiness from an artifact alone.
|
|
11
|
+
- If status is `IN_PROGRESS`, test implemented scope only and label incomplete flows accordingly. If status is `BLOCKED`, tests may be run only for an explicitly bounded existing scope; overall quality cannot be READY while the blocker remains unexplained.
|
|
12
|
+
- Implementation status `COMPLETE` permits testing; it does not prove quality.
|
|
13
|
+
|
|
14
|
+
Every test/security assertion uses one status: `PLANNED`, `EXECUTED`, `PASSED`, `FAILED`, `BLOCKED`, or `UNKNOWN`. A pass requires direct execution evidence (command/procedure, scope, result, and output or report). An unexecuted check is never PASSED. A missing test framework is `UNKNOWN` or `NOT PRESENT`, not FAILED. A broken/unavailable environment is `BLOCKED`.
|
|
15
|
+
|
|
16
|
+
Generated plans, reviews, and finding records are not independent execution evidence. Do not invent tool availability, test results, vulnerabilities, scan results, CI status, or dependency audit results.
|
|
17
|
+
|
|
18
|
+
## 2. Test baseline and categories
|
|
19
|
+
|
|
20
|
+
Record observed test framework/runner, test directories/files, scripts, build/lint/typecheck commands, API/E2E setup, CI, runtime, application structure, configuration/environment names, test data, fixtures, mocks, and known failures. Do not expose secret values. For each item state the evidence source or UNKNOWN.
|
|
21
|
+
|
|
22
|
+
Use only applicable categories: `UNIT`, `INTEGRATION`, `E2E`, `UI`, `API`, `SECURITY`, `PERFORMANCE`, `ACCESSIBILITY`, and `MANUAL`. No project must use all categories. Do not describe a script or test file as passing until it has actually been run.
|
|
23
|
+
|
|
24
|
+
Prioritize in order: critical user flows; MUST HAVE MVP behavior; authentication/authorization where applicable; data validation/integrity; API boundaries; error handling; security-sensitive paths; regression-prone areas; secondary features; optional features. Do not spend limited time on optional checks while critical flows remain unverified.
|
|
25
|
+
|
|
26
|
+
## 3. Test execution and failures
|
|
27
|
+
|
|
28
|
+
Use `templates/test-plan.md` at `.sherpa/test-plan.md` and `templates/test-result.md` at `.sherpa/testing/test-NNN.md`. Record planned tests separately from executed results. Before execution, state expected result and relevant scope. After execution, capture exact command/procedure, exit/result, relevant output, date/time, and affected revision when available.
|
|
29
|
+
|
|
30
|
+
- Mark a check `EXECUTED` while evidence is being recorded; mark `PASSED` only when observed results meet its expected result.
|
|
31
|
+
- Preserve failures as `FAILED` with output, impact, and affected component. Do not relabel them PASSED without a rerun that succeeds.
|
|
32
|
+
- If a test cannot run due to absent tools, dependencies, data, or environment, mark `BLOCKED` and identify the blocker. Do not install dependencies merely to make a test possible.
|
|
33
|
+
- Record tests not applicable with a reason; do not fabricate coverage.
|
|
34
|
+
|
|
35
|
+
## 4. Bounded security review
|
|
36
|
+
|
|
37
|
+
Use `templates/security-review.md` at `.sherpa/security-review.md` and `templates/security-finding.md` at `.sherpa/security/finding-NNN.md`. Every review states scope, files/areas inspected, method, limitations, and unknowns. Never claim a complete security audit from bounded inspection. Use the phrase `No confirmed vulnerabilities identified within the inspected scope.` only when it is accurate; it does not imply the whole application is safe.
|
|
38
|
+
|
|
39
|
+
Cover applicable areas: authentication, authorization/access control, input validation, output encoding, injection, secrets/environment, sensitive data, file/upload handling, API exposure, CORS, CSRF, XSS, SQL/NoSQL injection, command execution, path traversal, dependency vulnerabilities, rate limiting, logging, error leakage, and session/token handling. Mark uninspected or uncertain areas `UNKNOWN`. Classify observations `FACT`, `INFERENCE`, `ASSUMPTION`, or `UNKNOWN`, with source and confidence. Do not label a vulnerability without supporting evidence.
|
|
40
|
+
|
|
41
|
+
Use severity `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `INFO`, or `UNKNOWN`, based on exploitability, impact, affected surface, likelihood, and evidence. Do not inflate severity. Record confidence as `HIGH`, `MEDIUM`, `LOW`, or `UNKNOWN` separately from severity.
|
|
42
|
+
|
|
43
|
+
For dependency auditing, use an already-available project-native audit tool where practical. Record the exact command and results. If no appropriate tool is available, set dependency security status to `UNKNOWN`. Never install an auditor or automatically upgrade dependencies as part of review.
|
|
44
|
+
|
|
45
|
+
## 5. Remediation and regression
|
|
46
|
+
|
|
47
|
+
For each actionable finding record finding, impact, recommended remediation, approval/implementation decision required, focused verification method, and regression checks. Source changes and dependency upgrades are implementation work: route them through the approved Phase 4 process. Phase 5 may verify a fix after it exists; a proposed patch is not a fixed finding.
|
|
48
|
+
|
|
49
|
+
Mark a finding `FIXED` only after focused verification evidence passes. Meaningful fixes require identifying directly affected tests, related tests, critical user-flow checks, and security regression checks where applicable. If appropriate regression cannot run, status is `BLOCKED` or `UNKNOWN`, not verified.
|
|
50
|
+
|
|
51
|
+
## 6. Quality gate
|
|
52
|
+
|
|
53
|
+
Allowed quality gate values: `NOT_READY`, `TESTING_IN_PROGRESS`, `BLOCKED`, `CONDITIONAL`, `READY`.
|
|
54
|
+
|
|
55
|
+
`READY` requires all applicable critical tests to be executed and passed; critical failures resolved or explicitly accepted by a human; critical security findings fixed and verified or explicitly accepted by a human; no unexplained blocker; and evidence-backed status. A successful build alone is insufficient. Missing/unverified information, an open critical finding, or an unverified critical fix prevents READY. Keep the gate CONDITIONAL or BLOCKED when applicable tests, reviews, or regression evidence remain unavailable.
|
|
56
|
+
|
|
57
|
+
## 7. Time-aware testing
|
|
58
|
+
|
|
59
|
+
Use the existing project deadline/time. Do not calculate a false estimate or invent a deadline.
|
|
60
|
+
|
|
61
|
+
| Time remaining | Focus |
|
|
62
|
+
|---|---|
|
|
63
|
+
| >24h | Broad testing, security review, regression, and quality |
|
|
64
|
+
| 12–24h | MVP critical paths, security, high-value regression |
|
|
65
|
+
| 6–12h | Critical user flow, security-sensitive paths, demo reliability |
|
|
66
|
+
| 2–6h | Smoke tests, critical security checks, recent-change regression |
|
|
67
|
+
| <2h | Freeze features; test core demo, critical failures, obvious security risks, runtime-critical behavior |
|
|
68
|
+
| UNKNOWN | `TIME STRATEGY = UNKNOWN`; time-neutral prioritization |
|
|
69
|
+
|
|
70
|
+
## 8. Compact project state
|
|
71
|
+
|
|
72
|
+
Add/update only these Phase 5 fields in `.sherpa/project-state.md`:
|
|
73
|
+
|
|
74
|
+
| Field | Allowed values |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Testing status | `NOT_STARTED`, `IN_PROGRESS`, `BLOCKED`, `COMPLETE` |
|
|
77
|
+
| Test baseline | `UNKNOWN`, `VERIFIED` |
|
|
78
|
+
| Security review | `UNKNOWN`, `IN_PROGRESS`, `COMPLETE` |
|
|
79
|
+
| Critical test status | `UNKNOWN`, `PASS`, `FAIL`, `BLOCKED` |
|
|
80
|
+
| Critical security status | `UNKNOWN`, `PASS`, `FAIL`, `BLOCKED` |
|
|
81
|
+
| Quality gate | `NOT_READY`, `TESTING_IN_PROGRESS`, `BLOCKED`, `CONDITIONAL`, `READY` |
|
|
82
|
+
|
|
83
|
+
Do not add arbitrary fields or put detailed test/finding data in state. `Testing status = COMPLETE` means the defined Phase 5 test/review scope is complete, not that every test passed. Do not alter the selected idea, architecture, MVP, or Phase 4 implementation status.
|
|
84
|
+
|
|
85
|
+
## 9. Output
|
|
86
|
+
|
|
87
|
+
Return exactly one `PRIMARY NEXT ACTION`. Include readiness, scope, test/security status, executed evidence and failures, blockers/unknowns, quality gate, and one next action. Never start Phase 6.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# UX Review Rules
|
|
2
|
+
|
|
3
|
+
These rules are authoritative for the UX-REVIEW capability. UX review is lifecycle Phase 12; this is engineering capability Phase 7. Do not renumber or edit the 20-phase lifecycle.
|
|
4
|
+
|
|
5
|
+
## Purpose and boundaries
|
|
6
|
+
|
|
7
|
+
Evaluate whether the strongest user journeys are understandable, usable, reliable, accessible within a defined scope, responsive where tested, and convincing in a demo. Prioritize user outcomes over aesthetic preference. Review and recommend; do not change product scope, selected idea, approved Phase 3 architecture, Phase 4 implementation plan, or application source. Do not replace Phase 5 testing/security, judge simulation, score optimization, presentation, submission, or post-mortem work.
|
|
8
|
+
|
|
9
|
+
If a proposed remediation needs database/API redesign, authentication redesign, major frontend restructuring, service restructuring, or a major dependency change, record **ARCHITECTURE CHANGE REQUIRED**, why, evidence, impact, estimated effort, alternative, risk, and recommendation. Stop that remediation pending human-controlled architecture approval.
|
|
10
|
+
|
|
11
|
+
## Readiness and source of truth
|
|
12
|
+
|
|
13
|
+
Read `.sherpa/project-state.md`, the Phase 3 project plan, Phase 4 implementation plan/tasks, and Phase 5 test results/security review/findings before inspecting UX. UX review normally requires implementation READY/COMPLETE (or the project's explicit equivalent) and Phase 5 evidence showing the relevant scope is tested/reviewed. If implementation is NOT_STARTED, incomplete, or readiness cannot be established, report **UX review BLOCKED** or **NOT_READY**; do not imply a review occurred. A bounded static baseline may be offered only when clearly separated from a UX review and dynamic claims remain UNKNOWN.
|
|
14
|
+
|
|
15
|
+
Use the selected idea as context only. Never change it. Consume existing Phase 5 failures, blocked tests, security findings, and regression risks. If a UX question requires an automated or functional test, mark **TEST REQUIRED** and route it to the Phase 5 process; do not execute or duplicate that engine.
|
|
16
|
+
|
|
17
|
+
## Evidence model
|
|
18
|
+
|
|
19
|
+
Every claim is labeled FACT, INFERENCE, ASSUMPTION, or UNKNOWN. FACT identifies inspected source, UI, state, test, or direct observation. INFERENCE states its evidence and reasoning. ASSUMPTION is an explicit provisional premise. UNKNOWN includes what is missing and why. Every finding cites reproducible evidence: path/line, route/screen, viewport/device, steps, result, or evidence artifact. Never claim an interaction, viewport, assistive technology, or state was tested when it was not.
|
|
20
|
+
|
|
21
|
+
Never convert UNKNOWN into FACT. If evidence is unavailable, record UNKNOWN and explain what is missing and why.
|
|
22
|
+
|
|
23
|
+
Finding observation status is one of: OBSERVED, SUPPORTED, INFERRED, UNKNOWN, NOT_TESTED.
|
|
24
|
+
- OBSERVED: Directly visible or reproducible UX behavior.
|
|
25
|
+
- SUPPORTED: Strongly supported by available evidence such as screenshots, tests, source inspection, or runtime evidence.
|
|
26
|
+
- INFERRED: Reasonable conclusion based on available evidence but not directly verified.
|
|
27
|
+
- UNKNOWN: Insufficient evidence.
|
|
28
|
+
- NOT_TESTED: The relevant interaction or condition was not actually exercised.
|
|
29
|
+
|
|
30
|
+
Do not collapse these states. Finding workflow status is OPEN, IN_PROGRESS, FIXED, ACCEPTED_RISK, BLOCKED, or UNKNOWN. Do not confuse these status sets. A proposed change is not a fix. FIXED requires focused verification evidence and relevant regression consideration.
|
|
31
|
+
|
|
32
|
+
## Baseline and flow review
|
|
33
|
+
|
|
34
|
+
Inspect the actual project and record root/revision, frontend and backend relationship, routes/entry points, page/component structure, styles/design system/UI libraries, responsive CSS/breakpoints, forms/validation, loading/error/empty/success/disabled/retry/progress/confirmation states, navigation, authentication where applicable, accessibility semantics, test infrastructure, existing screenshots/evidence, known UX issues, and limitations. Mark absent or unavailable details UNKNOWN. If there is no frontend, record **UI = NOT PRESENT / UNKNOWN** and state the limited UX scope.
|
|
35
|
+
|
|
36
|
+
Review information architecture: content organization, page structure, grouping, terminology, discoverability, information density, and logical sequencing. Evaluate whether users can understand what belongs together, whether important information is easy to find, whether labels are meaningful, and whether the structure is predictable.
|
|
37
|
+
|
|
38
|
+
Identify and review relevant journeys in this order: first entry; primary value proposition; critical MVP action; result/output; error recovery; return/repeat use; demo/judge flow. For each flow record goal, target user, entry, preconditions, ordered steps, expected/observed outcome, friction, severity, evidence, observation status, and recommended action. A flow can be UNKNOWN or BLOCKED; never fabricate observed behavior.
|
|
39
|
+
|
|
40
|
+
Review clarity, labels, terminology, navigation/location, discoverability, actions, destructive intent, feedback, forms/validation/preserved input/defaults, content grouping, hierarchy, cognitive load, concrete visual hierarchy/usability consequences, and all applicable feedback states. Distinguish confirmed omissions from uninspected states.
|
|
41
|
+
|
|
42
|
+
## Accessibility and responsive boundaries
|
|
43
|
+
|
|
44
|
+
Record accessibility scope and limitations. Check applicable keyboard order and operability, visible focus, semantics, names/labels/form associations, contrast, zoom/text scaling, alternative text, ARIA correctness, error announcements, reduced motion, and touch target usability. Do not claim WCAG compliance without evaluation against a named version/level and defined scope. Prefer bounded language such as “No confirmed issue identified within the inspected scope.”
|
|
45
|
+
|
|
46
|
+
For responsive behavior record tested viewports and examine overflow/clipping, navigation, forms, controls, cards/tables/modals, touch behavior, spacing, and typography. Review mobile/tablet/desktop only when actually inspected. Untested sizes are UNKNOWN, never PASS.
|
|
47
|
+
|
|
48
|
+
## Findings and severity
|
|
49
|
+
|
|
50
|
+
Each finding includes a stable ID, title, category, severity, affected flow and component, concrete observation, evidence, user impact, reproduction steps, remediation, architecture impact, verification method, workflow status, and verification evidence. Categories: USABILITY, NAVIGATION, ACCESSIBILITY, RESPONSIVE, VISUAL_HIERARCHY, FORM, FEEDBACK, ERROR_HANDLING, ONBOARDING, CONTENT, CONSISTENCY, DEMO_FLOW, OTHER.
|
|
51
|
+
|
|
52
|
+
Confidence is recorded separately from severity as HIGH, MEDIUM, LOW, or UNKNOWN.
|
|
53
|
+
|
|
54
|
+
Severity considers flow criticality, frequency, blockage/confusion, accessibility and demo impact, recovery cost, and evidence confidence. CRITICAL blocks the primary journey or makes the demo fundamentally unusable; HIGH is major friction in a critical MVP flow; MEDIUM is meaningful with a workaround; LOW is minor friction/polish; INFO is an opportunity; UNKNOWN means evidence is insufficient. Do not inflate severity.
|
|
55
|
+
|
|
56
|
+
Priority uses P0, P1, P2, P3:
|
|
57
|
+
- P0: Critical UX blocker that prevents the primary task or demo; must be fixed or explicitly accepted.
|
|
58
|
+
- P1: High user/demo impact; fix before submission if time permits.
|
|
59
|
+
- P2: Meaningful UX weakness; fix after P0/P1 if time remains.
|
|
60
|
+
- P3: Minor polish; only if all higher priorities are complete.
|
|
61
|
+
|
|
62
|
+
Do not confuse severity and priority. HIGH severity does not automatically mean P0 if the fix cannot be safely completed within remaining time.
|
|
63
|
+
|
|
64
|
+
Conflicting UX evidence is recorded as a separate finding; do not silently reconcile contradictions between observations.
|
|
65
|
+
|
|
66
|
+
## Remediation, regression, and human authority
|
|
67
|
+
|
|
68
|
+
For each finding connect evidence → impact → recommendation → human/implementation decision when required → implementation through the existing Phase 4 process → focused UX verification → regression consideration (and Phase 5 test when needed) → evidence. Do not implement fixes as part of UX review. Do not mark FIXED without evidence. Do not mark a risk accepted without explicit human acceptance recorded in the project's decision evidence.
|
|
69
|
+
|
|
70
|
+
Phase 7 never changes architecture or selected idea. It may recommend and size a change; explicit human approval and the existing architecture/implementation processes are required. Do not claim regression passed without an executed check and result.
|
|
71
|
+
|
|
72
|
+
## Time strategy
|
|
73
|
+
|
|
74
|
+
- `>24h`: broad UX, accessibility, responsive review, then targeted polish.
|
|
75
|
+
- `12–24h`: critical flows, major usability, accessibility, demo polish.
|
|
76
|
+
- `6–12h`: critical journey, demo flow, obvious blockers, responsive essentials.
|
|
77
|
+
- `2–6h`: demo flow, navigation, forms, obvious breakage.
|
|
78
|
+
- `<2h`: freeze features; fix only demo blockers, critical usability/accessibility blockers, broken navigation/forms, or demo-device responsive failure.
|
|
79
|
+
- Unknown time: `TIME STRATEGY = UNKNOWN`; do not infer a deadline or remaining hours.
|
|
80
|
+
|
|
81
|
+
Within any window, critical blockers outrank low-impact visual polish.
|
|
82
|
+
|
|
83
|
+
## State, artifacts, and quality gate
|
|
84
|
+
|
|
85
|
+
Keep detailed evidence in `.sherpa/ux-review.md` and `.sherpa/ux/{flow-NNN,finding-NNN,verification-NNN}.md`. Add only these compact fields to the project's `.sherpa/project-state.md`, and only if the file already exists / is being legitimately updated by the workflow: UX status (`NOT_STARTED | IN_PROGRESS | BLOCKED | COMPLETE`); UX baseline (`UNKNOWN | VERIFIED`); Critical flows (`UNKNOWN | IDENTIFIED | REVIEWED`); Critical UX status (`UNKNOWN | PASS | FAIL | BLOCKED`); Accessibility status (`UNKNOWN | PASS | FAIL | BLOCKED`); Responsive status (`UNKNOWN | PASS | FAIL | BLOCKED`); UX quality gate (`NOT_READY | REVIEW_IN_PROGRESS | BLOCKED | CONDITIONAL | READY`). Do not change Phase 1 template/workflow files or add other state fields. Do not set UX COMPLETE merely because a review document exists.
|
|
86
|
+
|
|
87
|
+
Gate values: NOT_READY, REVIEW_IN_PROGRESS, BLOCKED, CONDITIONAL, READY. READY requires critical flows reviewed; no unexplained critical blocker; critical accessibility issues resolved or explicitly accepted; applicable critical responsive issues resolved or explicitly accepted; major navigation/usability issues addressed or accepted; findings evidence-backed; every claimed fix verified; and limitations documented. Unknown applicability or missing evidence prevents READY and may yield CONDITIONAL/BLOCKED. A polished appearance alone is insufficient.
|
|
88
|
+
|
|
89
|
+
Return exactly one **PRIMARY NEXT ACTION**, chosen from the highest-impact unresolved blocker or next required human decision. Do not create another NEXT/lifecycle engine. Never silently change scope or fabricate observations, tests, fixes, approvals, or remaining time.
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sherpa Configuration Manager
|
|
3
|
+
|
|
4
|
+
Defines authoritative Phase 1 behavior: initialization, collection, validation,
|
|
5
|
+
and persistent storage of project-specific information in `.env.sherpa`.
|
|
6
|
+
|
|
7
|
+
Design principles:
|
|
8
|
+
- `.env.sherpa` lives in the project repository root (NOT in the skill directory).
|
|
9
|
+
- `.env.hackathon` is read only as a deprecated fallback when the new file is absent.
|
|
10
|
+
- It is the single source of truth for project-specific configuration.
|
|
11
|
+
- All fields default to UNKNOWN until explicitly provided.
|
|
12
|
+
- Human-editable: users may edit directly; skill must preserve manual edits.
|
|
13
|
+
- No secrets: API keys and secrets go in `.env`, never in `.env.sherpa`.
|
|
14
|
+
- Idempotent: running init multiple times must not duplicate or destroy data.
|
|
15
|
+
|
|
16
|
+
Configuration categories:
|
|
17
|
+
HACKATHON_IDENTITY - hackathon name, platform, URL, dates, rules
|
|
18
|
+
PROBLEM_IDEA - problem statement, target users, selected idea, MVP
|
|
19
|
+
TECH_STACK - programming languages, frontend, backend, database, AI/ML
|
|
20
|
+
SUBMISSION - requirements, demo status, PPT status, deployment
|
|
21
|
+
TECHNICAL_CONSTRAINTS - budget, time, team size, constraints
|
|
22
|
+
ARCHITECTURE_DECISIONS - architecture summary, key differentiators
|
|
23
|
+
PROGRESS - completed work, current work, blocked work, risks
|
|
24
|
+
DELIVERABLES - demo status, PPT status, documentation, deployment URL
|
|
25
|
+
SUBMISSION - submission requirements, team info, team captain
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import configparser
|
|
31
|
+
import json
|
|
32
|
+
import os
|
|
33
|
+
import re
|
|
34
|
+
import sys
|
|
35
|
+
from dataclasses import dataclass, field
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Constants
|
|
42
|
+
# ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
ENV_SHERPA_FILENAME = ".env.sherpa"
|
|
45
|
+
LEGACY_ENV_FILENAME = ".env.hackathon"
|
|
46
|
+
ENV_FILE = ".env"
|
|
47
|
+
|
|
48
|
+
# Category -> list of field names
|
|
49
|
+
CATEGORY_FIELDS: dict[str, list[str]] = {
|
|
50
|
+
"HACKATHON_IDENTITY": [
|
|
51
|
+
"HACKATHON_NAME",
|
|
52
|
+
"HACKATHON_PLATFORM",
|
|
53
|
+
"HACKATHON_URL",
|
|
54
|
+
"HACKATHON_DASHBOARD_URL",
|
|
55
|
+
"START_DATE_TIME",
|
|
56
|
+
"DEADLINE_DATE_TIME",
|
|
57
|
+
"TIMEZONE",
|
|
58
|
+
"HACKATHON_ORGANIZER",
|
|
59
|
+
"HACKATHON_CONTACT",
|
|
60
|
+
"HACKATHON_THEME",
|
|
61
|
+
"ELIGIBILITY_REQUIREMENTS",
|
|
62
|
+
"PRIZE_INFORMATION",
|
|
63
|
+
],
|
|
64
|
+
"PROBLEM_IDEA": [
|
|
65
|
+
"PROBLEM_STATEMENT",
|
|
66
|
+
"TARGET_USERS",
|
|
67
|
+
"SELECTED_IDEA",
|
|
68
|
+
"PRODUCT_CONCEPT",
|
|
69
|
+
"MVP_SCOPE",
|
|
70
|
+
"MVP_FEATURES",
|
|
71
|
+
"KEY_DIFFERENTIATORS",
|
|
72
|
+
],
|
|
73
|
+
"TECH_STACK": [
|
|
74
|
+
"PROGRAMMING_LANGUAGES",
|
|
75
|
+
"FRONTEND_FRAMEWORK",
|
|
76
|
+
"BACKEND_FRAMEWORK",
|
|
77
|
+
"DATABASE",
|
|
78
|
+
"AI_ML_PROVIDER",
|
|
79
|
+
"AI_MODEL_NAME",
|
|
80
|
+
"DEPLOYMENT_PLATFORM",
|
|
81
|
+
"OTHER_TECHNOLOGIES",
|
|
82
|
+
],
|
|
83
|
+
"SUBMISSION": [
|
|
84
|
+
"DEMO_STATUS",
|
|
85
|
+
"PPT_STATUS",
|
|
86
|
+
"DOCUMENTATION_STATUS",
|
|
87
|
+
"DEPLOYMENT_URL",
|
|
88
|
+
"GITHUB_REPOSITORY_URL",
|
|
89
|
+
"DEMO_URL",
|
|
90
|
+
],
|
|
91
|
+
"TECHNICAL_CONSTRAINTS": [
|
|
92
|
+
"BUDGET_LIMIT",
|
|
93
|
+
"TIME_LIMIT",
|
|
94
|
+
"TEAM_SIZE",
|
|
95
|
+
"TECHNICAL_CONSTRAINTS",
|
|
96
|
+
],
|
|
97
|
+
"ARCHITECTURE_DECISIONS": [
|
|
98
|
+
"ARCHITECTURE_SUMMARY",
|
|
99
|
+
"IMPORTANT_DECISIONS",
|
|
100
|
+
"KNOWN_LIMITATIONS",
|
|
101
|
+
],
|
|
102
|
+
"PROGRESS": [
|
|
103
|
+
"COMPLETED_WORKSTREAMS",
|
|
104
|
+
"CURRENT_WORKSTREAM",
|
|
105
|
+
"BLOCKED_WORKSTREAMS",
|
|
106
|
+
"COMPLETED_FEATURES",
|
|
107
|
+
"MVP_STATUS",
|
|
108
|
+
],
|
|
109
|
+
"DELIVERABLES": [
|
|
110
|
+
"DEMO_STATUS",
|
|
111
|
+
"PPT_STATUS",
|
|
112
|
+
"DOCUMENTATION_STATUS",
|
|
113
|
+
"DEPLOYMENT_URL",
|
|
114
|
+
"GITHUB_REPOSITORY_URL",
|
|
115
|
+
"DEMO_URL",
|
|
116
|
+
],
|
|
117
|
+
"SUBMISSION": [
|
|
118
|
+
"SUBMISSION_REQUIREMENTS",
|
|
119
|
+
"OPTIONAL_DELIVERABLES",
|
|
120
|
+
"TEAM_NAME",
|
|
121
|
+
"TEAM_CAPTAIN",
|
|
122
|
+
"TEAM_MEMBERS",
|
|
123
|
+
"TEAM_CONTACT_EMAIL",
|
|
124
|
+
"TEAM_LOCATION",
|
|
125
|
+
],
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Fields that must never contain secrets
|
|
129
|
+
SECRET_FIELD_PATTERNS = [
|
|
130
|
+
re.compile(r".*API_KEY", re.IGNORECASE),
|
|
131
|
+
re.compile(r".*API_SECRET", re.IGNORECASE),
|
|
132
|
+
re.compile(r".*PASSWORD", re.IGNORECASE),
|
|
133
|
+
re.compile(r".*SECRET", re.IGNORECASE),
|
|
134
|
+
re.compile(r".*TOKEN", re.IGNORECASE),
|
|
135
|
+
re.compile(r".*PRIVATE_KEY", re.IGNORECASE),
|
|
136
|
+
re.compile(r".*CREDENTIAL", re.IGNORECASE),
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
# Default values for all known fields
|
|
140
|
+
DEFAULT_VALUES: dict[str, str] = {
|
|
141
|
+
# Hackathon Identity
|
|
142
|
+
"HACKATHON_NAME": "UNKNOWN",
|
|
143
|
+
"HACKATHON_PLATFORM": "UNKNOWN",
|
|
144
|
+
"HACKATHON_URL": "UNKNOWN",
|
|
145
|
+
"HACKATHON_DASHBOARD_URL": "UNKNOWN",
|
|
146
|
+
"START_DATE_TIME": "UNKNOWN",
|
|
147
|
+
"DEADLINE_DATE_TIME": "UNKNOWN",
|
|
148
|
+
"TIMEZONE": "UNKNOWN",
|
|
149
|
+
"HACKATHON_ORGANIZER": "UNKNOWN",
|
|
150
|
+
"HACKATHON_CONTACT": "UNKNOWN",
|
|
151
|
+
"HACKATHON_THEME": "UNKNOWN",
|
|
152
|
+
"ELIGIBILITY_REQUIREMENTS": "UNKNOWN",
|
|
153
|
+
"PRIZE_INFORMATION": "UNKNOWN",
|
|
154
|
+
# Problem & Idea
|
|
155
|
+
"PROBLEM_STATEMENT": "UNKNOWN",
|
|
156
|
+
"TARGET_USERS": "UNKNOWN",
|
|
157
|
+
"SELECTED_IDEA": "UNKNOWN",
|
|
158
|
+
"PRODUCT_CONCEPT": "UNKNOWN",
|
|
159
|
+
"MVP_SCOPE": "UNKNOWN",
|
|
160
|
+
"MVP_FEATURES": "UNKNOWN",
|
|
161
|
+
"KEY_DIFFERENTIATORS": "UNKNOWN",
|
|
162
|
+
# Tech Stack
|
|
163
|
+
"PROGRAMMING_LANGUAGES": "UNKNOWN",
|
|
164
|
+
"FRONTEND_FRAMEWORK": "UNKNOWN",
|
|
165
|
+
"BACKEND_FRAMEWORK": "UNKNOWN",
|
|
166
|
+
"DATABASE": "UNKNOWN",
|
|
167
|
+
"AI_ML_PROVIDER": "UNKNOWN",
|
|
168
|
+
"AI_MODEL_NAME": "UNKNOWN",
|
|
169
|
+
"DEPLOYMENT_PLATFORM": "UNKNOWN",
|
|
170
|
+
"OTHER_TECHNOLOGIES": "UNKNOWN",
|
|
171
|
+
# Submission
|
|
172
|
+
"DEMO_STATUS": "UNKNOWN",
|
|
173
|
+
"PPT_STATUS": "UNKNOWN",
|
|
174
|
+
"DOCUMENTATION_STATUS": "UNKNOWN",
|
|
175
|
+
"DEPLOYMENT_URL": "UNKNOWN",
|
|
176
|
+
"GITHUB_REPOSITORY_URL": "UNKNOWN",
|
|
177
|
+
"DEMO_URL": "UNKNOWN",
|
|
178
|
+
# Technical Constraints
|
|
179
|
+
"BUDGET_LIMIT": "UNKNOWN",
|
|
180
|
+
"TIME_LIMIT": "UNKNOWN",
|
|
181
|
+
"TEAM_SIZE": "UNKNOWN",
|
|
182
|
+
"TECHNICAL_CONSTRAINTS": "UNKNOWN",
|
|
183
|
+
# Architecture Decisions
|
|
184
|
+
"ARCHITECTURE_SUMMARY": "UNKNOWN",
|
|
185
|
+
"IMPORTANT_DECISIONS": "UNKNOWN",
|
|
186
|
+
"KNOWN_LIMITATIONS": "UNKNOWN",
|
|
187
|
+
# Progress
|
|
188
|
+
"COMPLETED_WORKSTREAMS": "UNKNOWN",
|
|
189
|
+
"CURRENT_WORKSTREAM": "UNKNOWN",
|
|
190
|
+
"BLOCKED_WORKSTREAMS": "UNKNOWN",
|
|
191
|
+
"COMPLETED_FEATURES": "UNKNOWN",
|
|
192
|
+
"MVP_STATUS": "UNKNOWN",
|
|
193
|
+
# Deliverables
|
|
194
|
+
"DEMO_STATUS": "UNKNOWN",
|
|
195
|
+
"PPT_STATUS": "UNKNOWN",
|
|
196
|
+
"DOCUMENTATION_STATUS": "UNKNOWN",
|
|
197
|
+
"DEPLOYMENT_URL": "UNKNOWN",
|
|
198
|
+
"GITHUB_REPOSITORY_URL": "UNKNOWN",
|
|
199
|
+
"DEMO_URL": "UNKNOWN",
|
|
200
|
+
# Submission
|
|
201
|
+
"SUBMISSION_REQUIREMENTS": "UNKNOWN",
|
|
202
|
+
"OPTIONAL_DELIVERABLES": "UNKNOWN",
|
|
203
|
+
"TEAM_NAME": "UNKNOWN",
|
|
204
|
+
"TEAM_CAPTAIN": "UNKNOWN",
|
|
205
|
+
"TEAM_MEMBERS": "UNKNOWN",
|
|
206
|
+
"TEAM_CONTACT_EMAIL": "UNKNOWN",
|
|
207
|
+
"TEAM_LOCATION": "UNKNOWN",
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class VerificationError(Exception):
|
|
212
|
+
"""Raised when configuration validation fails."""
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class ProjectConfig:
|
|
216
|
+
"""
|
|
217
|
+
Manages `.env.sherpa` — the persistent project state file.
|
|
218
|
+
|
|
219
|
+
Responsibilities:
|
|
220
|
+
- Initialize `.env.sherpa` if missing
|
|
221
|
+
- Load all fields into memory
|
|
222
|
+
- Update fields from user input or repository evidence
|
|
223
|
+
- Write changes back to disk (preserving comments and unknown fields)
|
|
224
|
+
- Validate values against expected formats
|
|
225
|
+
- Never write secrets to this file
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
def __init__(self, project_root: str | None = None):
|
|
229
|
+
self.project_root = Path(project_root or os.getcwd())
|
|
230
|
+
self.env_path = self.project_root / ENV_SHERPA_FILENAME
|
|
231
|
+
self.legacy_env_path = self.project_root / LEGACY_ENV_FILENAME
|
|
232
|
+
self.env_file = self.project_root / ".env"
|
|
233
|
+
self._config: dict[str, str] = {}
|
|
234
|
+
self._raw_lines: list[str] = []
|
|
235
|
+
self._loaded = False
|
|
236
|
+
self._changes: dict[str, str] = {}
|
|
237
|
+
|
|
238
|
+
# ------------------------------------------------------------------
|
|
239
|
+
# Loading / Saving
|
|
240
|
+
# ------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
def load(self) -> dict[str, str]:
|
|
243
|
+
"""Load .env.sherpa, or read the old filename as a deprecated fallback."""
|
|
244
|
+
self.env_path = self.project_root / ENV_SHERPA_FILENAME
|
|
245
|
+
source_path = self.env_path
|
|
246
|
+
if not source_path.exists() and self.legacy_env_path.exists():
|
|
247
|
+
import warnings
|
|
248
|
+
warnings.warn(".env.hackathon is deprecated; copy it to .env.sherpa. The original is preserved.", DeprecationWarning)
|
|
249
|
+
self._config = {}
|
|
250
|
+
self._raw_lines = []
|
|
251
|
+
|
|
252
|
+
if source_path.exists():
|
|
253
|
+
self._load_from_file(source_path)
|
|
254
|
+
else:
|
|
255
|
+
# Initialize with defaults
|
|
256
|
+
self._config = dict(DEFAULT_VALUES)
|
|
257
|
+
self._raw_lines = self._build_initial_lines()
|
|
258
|
+
self._write()
|
|
259
|
+
|
|
260
|
+
self._loaded = True
|
|
261
|
+
return dict(self._config)
|
|
262
|
+
|
|
263
|
+
def _load_from_file(self, path: Path) -> None:
|
|
264
|
+
"""Parse a Sherpa project environment file, preserving comments and blank lines."""
|
|
265
|
+
raw = path.read_text(encoding="utf-8")
|
|
266
|
+
self._raw_lines = raw.splitlines(keepends=True)
|
|
267
|
+
|
|
268
|
+
for line in self._raw_lines:
|
|
269
|
+
stripped = line.strip()
|
|
270
|
+
# Skip blank lines and comments
|
|
271
|
+
if not stripped or stripped.startswith("#"):
|
|
272
|
+
continue
|
|
273
|
+
# Parse KEY=VALUE
|
|
274
|
+
if "=" in stripped:
|
|
275
|
+
key, _, value = stripped.partition("=")
|
|
276
|
+
key = key.strip()
|
|
277
|
+
value = value.strip()
|
|
278
|
+
# Strip surrounding quotes
|
|
279
|
+
if len(value) >= 2 and value[0] == value[-1] and value[0] in ('"', "'"):
|
|
280
|
+
value = value[1:-1]
|
|
281
|
+
self._config[key] = value
|
|
282
|
+
|
|
283
|
+
# Fill in defaults for missing fields
|
|
284
|
+
for key, default_val in DEFAULT_VALUES.items():
|
|
285
|
+
if key not in self._config:
|
|
286
|
+
self._config[key] = default_val
|
|
287
|
+
|
|
288
|
+
def _build_initial_lines(self) -> list[str]:
|
|
289
|
+
"""Build initial .env.sherpa content from defaults."""
|
|
290
|
+
lines: list[str] = []
|
|
291
|
+
lines.append("# =============================================================================")
|
|
292
|
+
lines.append("# Hackathon Project State")
|
|
293
|
+
lines.add("")
|
|
294
|
+
lines.add("# This file is the persistent state for a sherpa-managed project.")
|
|
295
|
+
lines.add("# It lives in .sherpa/project-state.md inside the hackathon project's repository.")
|
|
296
|
+
lines.add("")
|
|
297
|
+
lines.add("# Any field whose value is not known must be set to UNKNOWN.")
|
|
298
|
+
lines.add("# Never invent or guess missing information.")
|
|
299
|
+
lines.add("")
|
|
300
|
+
lines.add("# =============================================================================")
|
|
301
|
+
lines.add("")
|
|
302
|
+
|
|
303
|
+
# Add sections based on categories
|
|
304
|
+
for category, fields in CATEGORY_FIELDS.items():
|
|
305
|
+
lines.append(f"# =============================================================================")
|
|
306
|
+
lines.append(f"# {category}")
|
|
307
|
+
lines.add(f"# =============================================================================")
|
|
308
|
+
lines.add("")
|
|
309
|
+
for field in fields:
|
|
310
|
+
value = DEFAULT_VALUES.get(field, "UNKNOWN")
|
|
311
|
+
lines.append(f'{field}="{value}"')
|
|
312
|
+
lines.append("")
|
|
313
|
+
|
|
314
|
+
return lines
|
|
315
|
+
|
|
316
|
+
def save(self) -> None:
|
|
317
|
+
"""Write current state to .env.sherpa, preserving comments and unknown fields."""
|
|
318
|
+
if not self.env_path:
|
|
319
|
+
raise RuntimeError("Verifier not initialized: call load() first")
|
|
320
|
+
|
|
321
|
+
lines: list[str] = []
|
|
322
|
+
seen_keys: set[str] = set()
|
|
323
|
+
|
|
324
|
+
# Preserve existing lines, updating values where we have new data
|
|
325
|
+
for line in self._raw_lines:
|
|
326
|
+
stripped = line.strip()
|
|
327
|
+
if not stripped or stripped.startswith("#"):
|
|
328
|
+
lines.append(line.rstrip("\n"))
|
|
329
|
+
continue
|
|
330
|
+
|
|
331
|
+
if "=" in stripped:
|
|
332
|
+
key, _, _ = stripped.partition("=")
|
|
333
|
+
key = key.strip()
|
|
334
|
+
if key in self._config:
|
|
335
|
+
lines.append(f'{key}="{self._config[key]}"')
|
|
336
|
+
seen_keys.add(key)
|
|
337
|
+
else:
|
|
338
|
+
lines.append(line.rstrip("\n"))
|
|
339
|
+
else:
|
|
340
|
+
lines.append(line.rstrip("\n"))
|
|
341
|
+
|
|
342
|
+
# Add any new keys not in original file
|
|
343
|
+
for key, value in self._config.items():
|
|
344
|
+
if key not in seen_keys:
|
|
345
|
+
lines.append(f'{key}="{value}"')
|
|
346
|
+
|
|
347
|
+
self._raw_lines = lines
|
|
348
|
+
self.env_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
349
|
+
|
|
350
|
+
# ------------------------------------------------------------------
|
|
351
|
+
# Get / Set
|
|
352
|
+
# ------------------------------------------------------------------
|
|
353
|
+
|
|
354
|
+
def get(self, key: str, default: str | None = None) -> str | None:
|
|
355
|
+
"""Get a configuration value."""
|
|
356
|
+
if not self._loaded:
|
|
357
|
+
self.load()
|
|
358
|
+
return self._config.get(key, default)
|
|
359
|
+
|
|
360
|
+
def set(self, key: str, value: str, source: str = "user") -> None:
|
|
361
|
+
"""Set a configuration value. Marks it as changed."""
|
|
362
|
+
if not self._loaded:
|
|
363
|
+
self.load()
|
|
364
|
+
self._config[key] = value
|
|
365
|
+
self._changes[key] = value
|
|
366
|
+
|
|
367
|
+
def get_all(self) -> dict[str, str]:
|
|
368
|
+
"""Return all configuration values."""
|
|
369
|
+
if not self._loaded:
|
|
370
|
+
self.load()
|
|
371
|
+
return dict(self._config)
|
|
372
|
+
|
|
373
|
+
def has(self, key: str) -> bool:
|
|
374
|
+
"""Check if a key exists."""
|
|
375
|
+
if not self._loaded:
|
|
376
|
+
self.load()
|
|
377
|
+
return key in self._config
|
|
378
|
+
|
|
379
|
+
def is_unknown(self, key: str) -> bool:
|
|
380
|
+
"""Check if a field is UNKNOWN."""
|
|
381
|
+
val = self.get(key)
|
|
382
|
+
return val == "UNKNOWN" or val == ""
|
|
383
|
+
|
|
384
|
+
def get_changes(self) -> dict[str, str]:
|
|
385
|
+
"""Return changes since last load."""
|
|
386
|
+
return dict(self._changes)
|
|
387
|
+
|
|
388
|
+
def mark_synced(self) -> None:
|
|
389
|
+
"""Mark all pending changes as synced."""
|
|
390
|
+
self._changes.clear()
|
|
391
|
+
|
|
392
|
+
# ------------------------------------------------------------------
|
|
393
|
+
# Validation
|
|
394
|
+
# ------------------------------------------------------------------
|
|
395
|
+
|
|
396
|
+
def validate(self) -> list[str]:
|
|
397
|
+
"""Validate all current values. Returns list of warning messages."""
|
|
398
|
+
warnings: list[str] = []
|
|
399
|
+
|
|
400
|
+
for key, value in self._config.items():
|
|
401
|
+
if not value or value == "UNKNOWN":
|
|
402
|
+
continue # Skip unknowns
|
|
403
|
+
|
|
404
|
+
# Check for potential secrets in non-secret fields
|
|
405
|
+
for pattern in _SECRET_PATTERNS:
|
|
406
|
+
if pattern.search(key):
|
|
407
|
+
warnings.append(
|
|
408
|
+
f"WARNING: '{key}' appears to contain a secret. "
|
|
409
|
+
f"Move to .env file instead."
|
|
410
|
+
)
|
|
411
|
+
break
|
|
412
|
+
|
|
413
|
+
return warnings
|
|
414
|
+
|
|
415
|
+
def validate_all(self) -> list[str]:
|
|
416
|
+
"""Alias for validate()."""
|
|
417
|
+
return self.validate()
|
|
418
|
+
|
|
419
|
+
# ------------------------------------------------------------------
|
|
420
|
+
# Convenience methods for common fields
|
|
421
|
+
# ------------------------------------------------------------------
|
|
422
|
+
|
|
423
|
+
def get_hackathon_name(self) -> str | None:
|
|
424
|
+
return self.get("HACKATHON_NAME")
|
|
425
|
+
|
|
426
|
+
def get_problem_statement(self) -> str | None:
|
|
427
|
+
return self.get("PROBLEM_STATEMENT")
|
|
428
|
+
|
|
429
|
+
def get_target_users(self) -> str | None:
|
|
430
|
+
return self.get("TARGET_USERS")
|
|
431
|
+
|
|
432
|
+
def get_selected_idea(self) -> str | None:
|
|
433
|
+
return self.get("SELECTED_IDEA")
|
|
434
|
+
|
|
435
|
+
def get_tech_stack(self) -> dict[str, str]:
|
|
436
|
+
return {
|
|
437
|
+
"programming_languages": self.get("PROGRAMMING_LANGUAGES"),
|
|
438
|
+
"frontend_framework": self.get("FRONTEND_FRAMEWORK"),
|
|
439
|
+
"backend_framework": self.get("BACKEND_FRAMEWORK"),
|
|
440
|
+
"database": self.get("DATABASE"),
|
|
441
|
+
"ai_ml_provider": self.get("AI_ML_PROVIDER"),
|
|
442
|
+
"ai_model_name": self.get("AI_MODEL_NAME"),
|
|
443
|
+
"deployment_platform": self.get("DEPLOYMENT_PLATFORM"),
|
|
444
|
+
"other_technologies": self.get("OTHER_TECHNOLOGIES"),
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
def get_submission_info(self) -> dict[str, str]:
|
|
448
|
+
return {
|
|
449
|
+
"deadline": self.get("DEADLINE_DATE_TIME"),
|
|
450
|
+
"requirements": self.get("SUBMISSION_REQUIREMENTS"),
|
|
451
|
+
"demo_status": self.get("DEMO_STATUS"),
|
|
452
|
+
"ppt_status": self.get("PPT_STATUS"),
|
|
453
|
+
"deployment_url": self.get("DEPLOYMENT_URL"),
|
|
454
|
+
"github_url": self.get("GITHUB_REPOSITORY_URL"),
|
|
455
|
+
"demo_url": self.get("DEMO_URL"),
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
# Singleton instance
|
|
460
|
+
_verifier: ProjectConfig | None = None
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def get_verifier(project_root: str | None = None) -> ProjectConfig:
|
|
464
|
+
"""Get or create the global verifier instance."""
|
|
465
|
+
global _verifier
|
|
466
|
+
if _verifier is None:
|
|
467
|
+
_verifier = ProjectConfig(project_root)
|
|
468
|
+
return _verifier
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def reset_verifier() -> None:
|
|
472
|
+
"""Reset the verifier singleton (mainly for testing)."""
|
|
473
|
+
global _verifier
|
|
474
|
+
_verifier = None
|