theslopmachine 0.6.2 → 0.7.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/MANUAL.md +21 -6
- package/README.md +55 -7
- package/RELEASE.md +15 -0
- package/assets/agents/developer.md +41 -1
- package/assets/agents/slopmachine-claude.md +100 -60
- package/assets/agents/slopmachine.md +40 -17
- package/assets/claude/agents/developer.md +42 -5
- package/assets/skills/clarification-gate/SKILL.md +25 -5
- package/assets/skills/claude-worker-management/SKILL.md +280 -57
- package/assets/skills/developer-session-lifecycle/SKILL.md +81 -37
- package/assets/skills/development-guidance/SKILL.md +21 -1
- package/assets/skills/evaluation-triage/SKILL.md +32 -23
- package/assets/skills/final-evaluation-orchestration/SKILL.md +86 -50
- package/assets/skills/hardening-gate/SKILL.md +17 -3
- package/assets/skills/integrated-verification/SKILL.md +3 -3
- package/assets/skills/planning-gate/SKILL.md +32 -3
- package/assets/skills/planning-guidance/SKILL.md +72 -13
- package/assets/skills/retrospective-analysis/SKILL.md +2 -2
- package/assets/skills/scaffold-guidance/SKILL.md +129 -124
- package/assets/skills/submission-packaging/SKILL.md +33 -27
- package/assets/skills/verification-gates/SKILL.md +44 -14
- package/assets/slopmachine/backend-evaluation-prompt.md +1 -1
- package/assets/slopmachine/frontend-evaluation-prompt.md +5 -5
- package/assets/slopmachine/scaffold-playbooks/android-kotlin-compose.md +81 -0
- package/assets/slopmachine/scaffold-playbooks/android-kotlin-views.md +191 -0
- package/assets/slopmachine/scaffold-playbooks/android-native-java.md +203 -0
- package/assets/slopmachine/scaffold-playbooks/angular-default.md +181 -0
- package/assets/slopmachine/scaffold-playbooks/backend-baseline.md +142 -0
- package/assets/slopmachine/scaffold-playbooks/backend-family-matrix.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/database-module-matrix.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/django-default.md +166 -0
- package/assets/slopmachine/scaffold-playbooks/docker-baseline.md +189 -0
- package/assets/slopmachine/scaffold-playbooks/docker-shared-contract.md +334 -0
- package/assets/slopmachine/scaffold-playbooks/electron-vite-default.md +124 -0
- package/assets/slopmachine/scaffold-playbooks/expo-react-native-default.md +73 -0
- package/assets/slopmachine/scaffold-playbooks/fastapi-default.md +134 -0
- package/assets/slopmachine/scaffold-playbooks/frontend-baseline.md +160 -0
- package/assets/slopmachine/scaffold-playbooks/frontend-family-matrix.md +134 -0
- package/assets/slopmachine/scaffold-playbooks/generic-unknown-tech-guide.md +136 -0
- package/assets/slopmachine/scaffold-playbooks/go-chi-default.md +160 -0
- package/assets/slopmachine/scaffold-playbooks/ios-linux-portable.md +93 -0
- package/assets/slopmachine/scaffold-playbooks/ios-native-objective-c.md +151 -0
- package/assets/slopmachine/scaffold-playbooks/ios-native-swift.md +188 -0
- package/assets/slopmachine/scaffold-playbooks/laravel-default.md +216 -0
- package/assets/slopmachine/scaffold-playbooks/livewire-default.md +265 -0
- package/assets/slopmachine/scaffold-playbooks/overlay-module-matrix.md +130 -0
- package/assets/slopmachine/scaffold-playbooks/platform-family-matrix.md +79 -0
- package/assets/slopmachine/scaffold-playbooks/selection-matrix.md +72 -0
- package/assets/slopmachine/scaffold-playbooks/spring-boot-default.md +182 -0
- package/assets/slopmachine/scaffold-playbooks/tauri-default.md +80 -0
- package/assets/slopmachine/scaffold-playbooks/vue-vite-default.md +162 -0
- package/assets/slopmachine/scaffold-playbooks/web-default.md +96 -0
- package/assets/slopmachine/templates/AGENTS.md +41 -3
- package/assets/slopmachine/templates/CLAUDE.md +111 -0
- package/assets/slopmachine/utils/claude_create_session.mjs +1 -0
- package/assets/slopmachine/utils/claude_live_channel.mjs +188 -0
- package/assets/slopmachine/utils/claude_live_common.mjs +406 -0
- package/assets/slopmachine/utils/claude_live_hook.py +47 -0
- package/assets/slopmachine/utils/claude_live_launch.mjs +181 -0
- package/assets/slopmachine/utils/claude_live_status.mjs +25 -0
- package/assets/slopmachine/utils/claude_live_stop.mjs +45 -0
- package/assets/slopmachine/utils/claude_live_turn.mjs +250 -0
- package/assets/slopmachine/utils/claude_resume_session.mjs +1 -0
- package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.mjs +23 -0
- package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.sh +5 -0
- package/assets/slopmachine/utils/claude_worker_common.mjs +224 -4
- package/assets/slopmachine/utils/cleanup_delivery_artifacts.py +4 -0
- package/assets/slopmachine/utils/export_ai_session.mjs +1 -1
- package/assets/slopmachine/utils/normalize_claude_session.py +153 -0
- package/assets/slopmachine/utils/package_claude_session.mjs +96 -0
- package/assets/slopmachine/utils/prepare_strict_audit_workspace.mjs +65 -0
- package/package.json +1 -1
- package/src/constants.js +42 -3
- package/src/init.js +173 -28
- package/src/install.js +75 -0
- package/src/send-data.js +56 -57
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Web Default Scaffold Playbook
|
|
2
|
+
|
|
3
|
+
Use this playbook for web frontend, backend, or fullstack requests unless the prompt or existing repo clearly requires a different runtime model.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Create a simple web baseline that:
|
|
8
|
+
|
|
9
|
+
- uses the requested framework or safest default bootstrap path
|
|
10
|
+
- runs through one honest primary runtime contract
|
|
11
|
+
- exposes one portable broad test command
|
|
12
|
+
- wires required baseline technologies without starting product-specific feature work
|
|
13
|
+
|
|
14
|
+
## Runtime contract
|
|
15
|
+
|
|
16
|
+
- required runtime command: `docker compose up --build`
|
|
17
|
+
- required broad test command: `./run_tests.sh`
|
|
18
|
+
- both commands must be real and working
|
|
19
|
+
|
|
20
|
+
## Bootstrap rule
|
|
21
|
+
|
|
22
|
+
- use the official or best-known bootstrap command for the requested web framework
|
|
23
|
+
- if the prompt leaves the framework open, choose the safest maintained default for the requested surface
|
|
24
|
+
- after bootstrap, adapt only enough to make the runtime, test path, config path, and README honest
|
|
25
|
+
|
|
26
|
+
## Required scripts
|
|
27
|
+
|
|
28
|
+
- `./run_tests.sh`
|
|
29
|
+
- `./init_db.sh` when the project has database dependencies
|
|
30
|
+
|
|
31
|
+
## Safe defaults
|
|
32
|
+
|
|
33
|
+
- no `.env` files in the repo
|
|
34
|
+
- no hardcoded secrets
|
|
35
|
+
- Docker runtime is mandatory for web delivery
|
|
36
|
+
- only app-facing services exposed to host by default
|
|
37
|
+
- internal services kept off host ports unless genuinely needed
|
|
38
|
+
- `COMPOSE_PROJECT_NAME` namespaced cleanly when Docker is used
|
|
39
|
+
|
|
40
|
+
## Baseline structure
|
|
41
|
+
|
|
42
|
+
- app/runtime entrypoints are real
|
|
43
|
+
- test tooling is installed
|
|
44
|
+
- config flow is explicit
|
|
45
|
+
- logging/validation baseline exists where the stack obviously needs it
|
|
46
|
+
- repo `README.md` is honest from day one
|
|
47
|
+
|
|
48
|
+
## `./run_tests.sh`
|
|
49
|
+
|
|
50
|
+
For the default Docker-first model, `./run_tests.sh` should own the portable broad path and remain runnable on a clean Linux machine with Docker and curl.
|
|
51
|
+
|
|
52
|
+
Typical baseline coverage:
|
|
53
|
+
|
|
54
|
+
- install/build health
|
|
55
|
+
- lint or typecheck when applicable
|
|
56
|
+
- one or more real baseline tests
|
|
57
|
+
- app or API smoke-level verification
|
|
58
|
+
|
|
59
|
+
## Minimal real test floor
|
|
60
|
+
|
|
61
|
+
At scaffold, include at least:
|
|
62
|
+
|
|
63
|
+
- one real unit or route/component test
|
|
64
|
+
- one real smoke-level proof that the chosen framework wiring works
|
|
65
|
+
- one real broad-path build/test invocation in `./run_tests.sh`
|
|
66
|
+
|
|
67
|
+
Do not leave the broad path mostly empty.
|
|
68
|
+
|
|
69
|
+
## README floor
|
|
70
|
+
|
|
71
|
+
`README.md` must already state:
|
|
72
|
+
|
|
73
|
+
- scaffold status versus implemented scope
|
|
74
|
+
- required Docker command: `docker compose up --build`
|
|
75
|
+
- broad test command
|
|
76
|
+
- main repo layout
|
|
77
|
+
- any mock/local-only or scaffold honesty boundaries
|
|
78
|
+
|
|
79
|
+
## Common pitfalls
|
|
80
|
+
|
|
81
|
+
- pretending a non-Docker web runtime is acceptable as the final baseline contract
|
|
82
|
+
- checked-in `.env` files
|
|
83
|
+
- hardcoded secret literals in Compose or startup scripts
|
|
84
|
+
- exposing every service port to host by default
|
|
85
|
+
- generating a giant scaffold with almost no real tests
|
|
86
|
+
|
|
87
|
+
## Acceptance checklist
|
|
88
|
+
|
|
89
|
+
Scaffold is acceptable when:
|
|
90
|
+
|
|
91
|
+
- `docker compose up --build` works
|
|
92
|
+
- `./run_tests.sh` works
|
|
93
|
+
- required baseline technologies are wired
|
|
94
|
+
- minimal real tests exist
|
|
95
|
+
- README is honest
|
|
96
|
+
- no `.env` or hardcoded secret residue exists
|
|
@@ -16,6 +16,28 @@ This file is the repo-local engineering rulebook for `slopmachine` projects.
|
|
|
16
16
|
- Work in meaningful vertical slices.
|
|
17
17
|
- Do not call work complete while it is still shaky.
|
|
18
18
|
- Reuse and extend shared cross-cutting patterns instead of inventing incompatible local ones.
|
|
19
|
+
- Before coding, identify the actors or personas touched by the change and the concrete path to success for each one.
|
|
20
|
+
- Make important business rules explicit before coding: defaults, limits, allowed transitions, uniqueness, conflicts, reversals, retries, and ownership rules when they matter.
|
|
21
|
+
- When the product has meaningful workflow state, define or confirm the relevant state machine before treating the flow as implemented.
|
|
22
|
+
- Keep a concrete out-of-scope boundary in mind so you do not overbuild speculative features.
|
|
23
|
+
- Do not introduce convenience-based `v1` scope cuts, role simplifications, or workflow omissions unless they were explicitly authorized.
|
|
24
|
+
- When backend or fullstack API endpoints are added or changed, prefer real HTTP tests for the exact `METHOD + PATH` over controller or service bypasses when practical.
|
|
25
|
+
- If mocked HTTP tests or unit-only tests still exist for an API surface, do not overstate them as equivalent to true no-mock endpoint coverage.
|
|
26
|
+
|
|
27
|
+
## Requirements Fidelity
|
|
28
|
+
|
|
29
|
+
- Preserve the full prompt intent, including implied business constraints.
|
|
30
|
+
- Do not weaken required actor models, operator flows, security controls, or lifecycle behavior for implementation convenience.
|
|
31
|
+
- If a requirement is ambiguous, choose the safest prompt-faithful behavior or surface the ambiguity instead of guessing lazily.
|
|
32
|
+
- If the feature depends on business rules, make those rules traceable in code, tests, and `README.md` rather than leaving them implicit.
|
|
33
|
+
|
|
34
|
+
## Architecture Rules
|
|
35
|
+
|
|
36
|
+
- For backend or fullstack projects, route configuration through a central config module instead of scattering direct environment reads through business logic.
|
|
37
|
+
- Keep database operations, business logic, transport layers, and UI surfaces separated clearly enough for static review.
|
|
38
|
+
- Use a shared logging path and shared validation/error-normalization path when the project is large enough for those concerns to matter.
|
|
39
|
+
- When a third-party service is required but real integration is not explicitly demanded, prefer an internal stub or adaptor boundary over shipping brittle real credentials or uncontrolled external dependencies.
|
|
40
|
+
- If a feature requires auth or privileged access, enforce it across route, controller or handler, and object scope where applicable.
|
|
19
41
|
|
|
20
42
|
## Runtime And Verification
|
|
21
43
|
|
|
@@ -26,8 +48,9 @@ This file is the repo-local engineering rulebook for `slopmachine` projects.
|
|
|
26
48
|
- During ordinary development slices, do not run Docker runtime commands, browser E2E, Playwright, full test suites, or `./run_tests.sh`.
|
|
27
49
|
- Use targeted local tests during ordinary development slices and leave browser E2E plus broad-gate commands for later comprehensive verification.
|
|
28
50
|
- When API tests are material, make them hit real endpoints and print simple useful response evidence such as status codes and message/body summaries.
|
|
29
|
-
- For web projects,
|
|
30
|
-
-
|
|
51
|
+
- For web projects, require the runtime contract to be `docker compose up --build`.
|
|
52
|
+
- For Android, mobile, desktop, and iOS-targeted projects, also require a meaningful `docker compose up --build` command even when platform-specific runtime proof differs from web semantics.
|
|
53
|
+
- For non-web projects, `./run_app.sh` may exist as a helper wrapper, but it does not replace the required Docker command.
|
|
31
54
|
- If the project has database dependencies, keep `./init_db.sh` as the only project-standard database initialization path.
|
|
32
55
|
|
|
33
56
|
## Documentation Rules
|
|
@@ -35,17 +58,21 @@ This file is the repo-local engineering rulebook for `slopmachine` projects.
|
|
|
35
58
|
- Keep `README.md` accurate.
|
|
36
59
|
- The README must explain what the project is, what it does, how to run it, how to test it, the main repo contents, and any important information a new developer needs immediately.
|
|
37
60
|
- The README must also explain the delivered architecture and major implementation structure clearly enough for review and handoff.
|
|
38
|
-
- The README must
|
|
61
|
+
- The README must include project type near the top, startup instructions, access method, verification method, and demo credentials for every role or the exact statement `No authentication required`.
|
|
62
|
+
- The README must clearly document the required Docker command `docker compose up --build` and any additional helper runtime wrapper such as `./run_app.sh` when present.
|
|
39
63
|
- The README must clearly document `./run_tests.sh` as the broad test command.
|
|
64
|
+
- For backend, fullstack, and web projects, the README should also contain the exact legacy compatibility string `docker-compose up` somewhere in startup guidance without replacing the canonical runtime contract.
|
|
40
65
|
- The README must stand on its own for basic codebase use.
|
|
41
66
|
- Keep `README.md` as the only documentation file inside the repo unless the user explicitly asks for something else.
|
|
42
67
|
- Treat `README.md` as the primary documentation surface inside the repo.
|
|
43
68
|
- The repo should be statically reviewable by a fresh reviewer: entry points, routes, config, test commands, and major module boundaries should be traceable from repository artifacts.
|
|
69
|
+
- The README should name the important actors, the main success paths, major limitations or out-of-scope boundaries, and any non-obvious business rules that affect usage.
|
|
44
70
|
- If the project uses mock, stub, fake, interception, or local-data behavior, the README must disclose that scope accurately.
|
|
45
71
|
- If mock or interception behavior is enabled by default, the README must say so clearly.
|
|
46
72
|
- Feature flags, debug/demo surfaces, default enabled states, and mock/interception defaults must be disclosed in `README.md` when they exist.
|
|
47
73
|
- Do not let a mock-only or local-data-only project look like undisclosed real backend or production integration.
|
|
48
74
|
- Do not hide missing failure handling behind fake-success paths.
|
|
75
|
+
- Before final delivery, remove local-only setup traces and host-only dependency assumptions from the README and wrapper scripts.
|
|
49
76
|
|
|
50
77
|
## Secret And Runtime Rules
|
|
51
78
|
|
|
@@ -67,6 +94,17 @@ This file is the repo-local engineering rulebook for `slopmachine` projects.
|
|
|
67
94
|
- Do not leave placeholder, setup, debug, or demo content in product-facing UI.
|
|
68
95
|
- If a real user-facing or admin-facing surface is required, build that surface instead of bypassing it with API shortcuts.
|
|
69
96
|
- Treat missing real surfaces as incomplete implementation.
|
|
97
|
+
- If multiple roles or personas exist, implement the real role-aware surfaces and permissions rather than collapsing them into a single generic flow.
|
|
98
|
+
- Do not replace prompt-required interaction models, lifecycle behavior, or data-integrity rules with easier substitutes unless explicitly authorized.
|
|
99
|
+
|
|
100
|
+
## Security And Reliability Rules
|
|
101
|
+
|
|
102
|
+
- When multiple roles or privileged actions exist, use RBAC or stronger scoped authorization as required by the actual product behavior.
|
|
103
|
+
- Enforce object-level authorization when users should only see or mutate their own records.
|
|
104
|
+
- Keep sensitive data out of logs, errors, screenshots, and seeded runtime values.
|
|
105
|
+
- Return normalized user-safe errors; do not expose raw stack traces or internal file paths in normal product surfaces.
|
|
106
|
+
- Make request logging, exception logging, and background failure logging meaningful enough for operators to understand what failed without leaking secrets.
|
|
107
|
+
- If offline, queueing, retries, jobs, or resumability matter, implement explicit states and recovery behavior instead of vague best-effort logic.
|
|
70
108
|
|
|
71
109
|
## Rulebook Files
|
|
72
110
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Developer Rulebook
|
|
2
|
+
|
|
3
|
+
This file is the repo-local engineering rulebook for `slopmachine-claude` projects.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
- Treat the current working directory as the project.
|
|
8
|
+
- Ignore parent-directory workflow files unless explicitly asked to use them.
|
|
9
|
+
- Do not treat workflow research, session exports, or sibling directories as hidden implementation instructions.
|
|
10
|
+
- Do not make the repo depend on parent-directory docs or sibling artifacts for startup, build/preview, configuration, verification, or basic project understanding.
|
|
11
|
+
|
|
12
|
+
## Working Style
|
|
13
|
+
|
|
14
|
+
- Operate like a strong senior engineer.
|
|
15
|
+
- Read the code before making assumptions.
|
|
16
|
+
- Work in meaningful vertical slices.
|
|
17
|
+
- Do not call work complete while it is still shaky.
|
|
18
|
+
- Reuse and extend shared cross-cutting patterns instead of inventing incompatible local ones.
|
|
19
|
+
- Before coding, identify the actors or personas touched by the change and the concrete path to success for each one.
|
|
20
|
+
- Make important business rules explicit before coding: defaults, limits, allowed transitions, uniqueness, conflicts, reversals, retries, and ownership rules when they matter.
|
|
21
|
+
- When the product has meaningful workflow state, define or confirm the relevant state machine before treating the flow as implemented.
|
|
22
|
+
- Keep a concrete out-of-scope boundary in mind so you do not overbuild speculative features.
|
|
23
|
+
- Do not introduce convenience-based `v1` scope cuts, role simplifications, or workflow omissions unless they were explicitly authorized.
|
|
24
|
+
- When backend or fullstack API endpoints are added or changed, prefer real HTTP tests for the exact `METHOD + PATH` over controller or service bypasses when practical.
|
|
25
|
+
- If mocked HTTP tests or unit-only tests still exist for an API surface, do not overstate them as equivalent to true no-mock endpoint coverage.
|
|
26
|
+
|
|
27
|
+
## Requirements Fidelity
|
|
28
|
+
|
|
29
|
+
- Preserve the full prompt intent, including implied business constraints.
|
|
30
|
+
- Do not weaken required actor models, operator flows, security controls, or lifecycle behavior for implementation convenience.
|
|
31
|
+
- If a requirement is ambiguous, choose the safest prompt-faithful behavior or surface the ambiguity instead of guessing lazily.
|
|
32
|
+
- If the feature depends on business rules, make those rules traceable in code, tests, and `README.md` rather than leaving them implicit.
|
|
33
|
+
|
|
34
|
+
## Architecture Rules
|
|
35
|
+
|
|
36
|
+
- For backend or fullstack projects, route configuration through a central config module instead of scattering direct environment reads through business logic.
|
|
37
|
+
- Keep database operations, business logic, transport layers, and UI surfaces separated clearly enough for static review.
|
|
38
|
+
- Use a shared logging path and shared validation/error-normalization path when the project is large enough for those concerns to matter.
|
|
39
|
+
- When a third-party service is required but real integration is not explicitly demanded, prefer an internal stub or adaptor boundary over shipping brittle real credentials or uncontrolled external dependencies.
|
|
40
|
+
- If a feature requires auth or privileged access, enforce it across route, controller or handler, and object scope where applicable.
|
|
41
|
+
|
|
42
|
+
## Runtime And Verification
|
|
43
|
+
|
|
44
|
+
- Keep one primary documented runtime command and one primary broad test command: `./run_tests.sh`.
|
|
45
|
+
- Follow the original prompt and existing repository first for the runtime stack.
|
|
46
|
+
- Prefer the fastest meaningful local verification for the changed area during ordinary iteration.
|
|
47
|
+
- Do not rerun broad runtime/test commands on every small change.
|
|
48
|
+
- During ordinary development slices, do not run Docker runtime commands, browser E2E, Playwright, full test suites, or `./run_tests.sh`.
|
|
49
|
+
- Use targeted local tests during ordinary development slices and leave browser E2E plus broad-gate commands for later comprehensive verification.
|
|
50
|
+
- When API tests are material, make them hit real endpoints and print simple useful response evidence such as status codes and message/body summaries.
|
|
51
|
+
- For web projects, require the runtime contract to be `docker compose up --build`.
|
|
52
|
+
- For Android, mobile, desktop, and iOS-targeted projects, also require a meaningful `docker compose up --build` command even when platform-specific runtime proof differs from web semantics.
|
|
53
|
+
- For non-web projects, `./run_app.sh` may exist as a helper wrapper, but it does not replace the required Docker command.
|
|
54
|
+
- If the project has database dependencies, keep `./init_db.sh` as the only project-standard database initialization path.
|
|
55
|
+
|
|
56
|
+
## Documentation Rules
|
|
57
|
+
|
|
58
|
+
- Keep `README.md` accurate.
|
|
59
|
+
- The README must explain what the project is, what it does, how to run it, how to test it, the main repo contents, and any important information a new developer needs immediately.
|
|
60
|
+
- The README must also explain the delivered architecture and major implementation structure clearly enough for review and handoff.
|
|
61
|
+
- The README must include project type near the top, startup instructions, access method, verification method, and demo credentials for every role or the exact statement `No authentication required`.
|
|
62
|
+
- The README must clearly document the required Docker command `docker compose up --build` and any additional helper runtime wrapper such as `./run_app.sh` when present.
|
|
63
|
+
- The README must clearly document `./run_tests.sh` as the broad test command.
|
|
64
|
+
- For backend, fullstack, and web projects, the README should also contain the exact legacy compatibility string `docker-compose up` somewhere in startup guidance without replacing the canonical runtime contract.
|
|
65
|
+
- The README must stand on its own for basic codebase use.
|
|
66
|
+
- Keep `README.md` as the only documentation file inside the repo unless the user explicitly asks for something else.
|
|
67
|
+
- Treat `README.md` as the primary documentation surface inside the repo.
|
|
68
|
+
- The repo should be statically reviewable by a fresh reviewer: entry points, routes, config, test commands, and major module boundaries should be traceable from repository artifacts.
|
|
69
|
+
- The README should name the important actors, the main success paths, major limitations or out-of-scope boundaries, and any non-obvious business rules that affect usage.
|
|
70
|
+
- If the project uses mock, stub, fake, interception, or local-data behavior, the README must disclose that scope accurately.
|
|
71
|
+
- If mock or interception behavior is enabled by default, the README must say so clearly.
|
|
72
|
+
- Feature flags, debug/demo surfaces, default enabled states, and mock/interception defaults must be disclosed in `README.md` when they exist.
|
|
73
|
+
- Do not let a mock-only or local-data-only project look like undisclosed real backend or production integration.
|
|
74
|
+
- Do not hide missing failure handling behind fake-success paths.
|
|
75
|
+
- Before final delivery, remove local-only setup traces and host-only dependency assumptions from the README and wrapper scripts.
|
|
76
|
+
|
|
77
|
+
## Secret And Runtime Rules
|
|
78
|
+
|
|
79
|
+
- Do not create or keep `.env` files anywhere in the repo.
|
|
80
|
+
- Do not rely on `.env`, `.env.local`, `.env.example`, or similar files for project startup.
|
|
81
|
+
- Do not hardcode secrets.
|
|
82
|
+
- If runtime env-file format is required, generate it ephemerally and do not commit or package it.
|
|
83
|
+
- Do not hardcode database connection values or database bootstrap values anywhere in the repo.
|
|
84
|
+
- For Dockerized web projects, `docker compose up --build` should work without any manual `export ...` step.
|
|
85
|
+
- For Dockerized web projects, prefer a dev-only runtime bootstrap script that is invoked automatically by the Docker startup path to generate or inject local-development runtime values.
|
|
86
|
+
- That bootstrap path must not use checked-in `.env` files or hardcoded runtime values.
|
|
87
|
+
- Do not pre-seed secret literals in Compose files, config files, Dockerfiles, or startup scripts even if they are labeled dev-only, test-only, or non-production.
|
|
88
|
+
- `./run_tests.sh` should use the same startup-value model as `docker compose up --build` rather than a separate pre-seeded test-secret path.
|
|
89
|
+
- If local-development runtime values must persist across restarts, keep them only in Docker-managed runtime state rather than committed repo files.
|
|
90
|
+
- If such a bootstrap script exists, document in the script and in `README.md` that it is for local development bootstrap only and is not the production secret-management path.
|
|
91
|
+
|
|
92
|
+
## Product Integrity Rules
|
|
93
|
+
|
|
94
|
+
- Do not leave placeholder, setup, debug, or demo content in product-facing UI.
|
|
95
|
+
- If a real user-facing or admin-facing surface is required, build that surface instead of bypassing it with API shortcuts.
|
|
96
|
+
- Treat missing real surfaces as incomplete implementation.
|
|
97
|
+
- If multiple roles or personas exist, implement the real role-aware surfaces and permissions rather than collapsing them into a single generic flow.
|
|
98
|
+
- Do not replace prompt-required interaction models, lifecycle behavior, or data-integrity rules with easier substitutes unless explicitly authorized.
|
|
99
|
+
|
|
100
|
+
## Security And Reliability Rules
|
|
101
|
+
|
|
102
|
+
- When multiple roles or privileged actions exist, use RBAC or stronger scoped authorization as required by the actual product behavior.
|
|
103
|
+
- Enforce object-level authorization when users should only see or mutate their own records.
|
|
104
|
+
- Keep sensitive data out of logs, errors, screenshots, and seeded runtime values.
|
|
105
|
+
- Return normalized user-safe errors; do not expose raw stack traces or internal file paths in normal product surfaces.
|
|
106
|
+
- Make request logging, exception logging, and background failure logging meaningful enough for operators to understand what failed without leaking secrets.
|
|
107
|
+
- If offline, queueing, retries, jobs, or resumability matter, implement explicit states and recovery behavior instead of vague best-effort logic.
|
|
108
|
+
|
|
109
|
+
## Rulebook Files
|
|
110
|
+
|
|
111
|
+
- Do not edit `CLAUDE.md` or other workflow/rulebook files unless explicitly asked.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import http from 'node:http'
|
|
4
|
+
import fs from 'node:fs/promises'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
|
|
7
|
+
import { parseArgs, writeJsonIfNeeded } from './claude_worker_common.mjs'
|
|
8
|
+
|
|
9
|
+
const argv = parseArgs(process.argv.slice(2))
|
|
10
|
+
const port = Number.parseInt(argv.port, 10)
|
|
11
|
+
const token = argv.token
|
|
12
|
+
const stateFile = argv['state-file']
|
|
13
|
+
const logFile = argv['log-file']
|
|
14
|
+
const channelName = argv['channel-name'] || 'slopmachine-channel'
|
|
15
|
+
const lane = argv.lane || 'lane'
|
|
16
|
+
|
|
17
|
+
const instructions = 'Messages arrive as <channel source="slopmachine" ...>. Treat them as ordinary inbound work requests and respond normally in the current Claude session. Do not look for or use any reply tool for this channel.'
|
|
18
|
+
|
|
19
|
+
let buffer = ''
|
|
20
|
+
let readyForNotifications = false
|
|
21
|
+
let negotiatedProtocolVersion = '2025-11-25'
|
|
22
|
+
|
|
23
|
+
function writeMessage(message) {
|
|
24
|
+
process.stdout.write(`${JSON.stringify(message)}\n`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function appendLog(record) {
|
|
28
|
+
const line = `${JSON.stringify({ ts: new Date().toISOString(), ...record })}\n`
|
|
29
|
+
await fs.mkdir(path.dirname(logFile), { recursive: true })
|
|
30
|
+
await fs.appendFile(logFile, line, 'utf8')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function updateState(patch) {
|
|
34
|
+
await writeJsonIfNeeded(stateFile, {
|
|
35
|
+
channel_name: channelName,
|
|
36
|
+
lane,
|
|
37
|
+
pid: process.pid,
|
|
38
|
+
port,
|
|
39
|
+
ready_for_notifications: readyForNotifications,
|
|
40
|
+
protocol_version: negotiatedProtocolVersion,
|
|
41
|
+
updated_at: new Date().toISOString(),
|
|
42
|
+
...patch,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function handleRpc(message) {
|
|
47
|
+
if (message.method === 'initialize' && Object.prototype.hasOwnProperty.call(message, 'id')) {
|
|
48
|
+
negotiatedProtocolVersion = message.params?.protocolVersion || negotiatedProtocolVersion
|
|
49
|
+
await updateState({ status: 'initialized' })
|
|
50
|
+
writeMessage({
|
|
51
|
+
jsonrpc: '2.0',
|
|
52
|
+
id: message.id,
|
|
53
|
+
result: {
|
|
54
|
+
protocolVersion: negotiatedProtocolVersion,
|
|
55
|
+
capabilities: {
|
|
56
|
+
experimental: {
|
|
57
|
+
'claude/channel': {},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
serverInfo: {
|
|
61
|
+
name: channelName,
|
|
62
|
+
version: '0.1.0',
|
|
63
|
+
},
|
|
64
|
+
instructions,
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
await appendLog({ type: 'initialize', message })
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (message.method === 'notifications/initialized') {
|
|
72
|
+
readyForNotifications = true
|
|
73
|
+
await updateState({ status: 'ready' })
|
|
74
|
+
await appendLog({ type: 'initialized' })
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (message.method === 'ping' && Object.prototype.hasOwnProperty.call(message, 'id')) {
|
|
79
|
+
writeMessage({ jsonrpc: '2.0', id: message.id, result: {} })
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (Object.prototype.hasOwnProperty.call(message, 'id')) {
|
|
84
|
+
writeMessage({
|
|
85
|
+
jsonrpc: '2.0',
|
|
86
|
+
id: message.id,
|
|
87
|
+
error: {
|
|
88
|
+
code: -32601,
|
|
89
|
+
message: `Method not found: ${message.method}`,
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
process.stdin.setEncoding('utf8')
|
|
96
|
+
process.stdin.on('data', async (chunk) => {
|
|
97
|
+
buffer += chunk
|
|
98
|
+
while (true) {
|
|
99
|
+
const newlineIndex = buffer.indexOf('\n')
|
|
100
|
+
if (newlineIndex === -1) {
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
const line = buffer.slice(0, newlineIndex).trim()
|
|
104
|
+
buffer = buffer.slice(newlineIndex + 1)
|
|
105
|
+
if (!line) {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const message = JSON.parse(line)
|
|
110
|
+
await handleRpc(message)
|
|
111
|
+
} catch (error) {
|
|
112
|
+
await updateState({ status: 'failed', last_error: error instanceof Error ? error.message : String(error) })
|
|
113
|
+
await appendLog({ type: 'rpc_error', error: error instanceof Error ? error.message : String(error) })
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
process.stdin.on('end', async () => {
|
|
119
|
+
await updateState({ status: 'closed' })
|
|
120
|
+
process.exit(0)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
await updateState({ status: 'starting' })
|
|
124
|
+
|
|
125
|
+
const server = http.createServer(async (request, response) => {
|
|
126
|
+
if (request.method !== 'POST') {
|
|
127
|
+
response.writeHead(404)
|
|
128
|
+
response.end('not found')
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (request.headers['x-bridge-token'] !== token) {
|
|
133
|
+
response.writeHead(403)
|
|
134
|
+
response.end('forbidden')
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!readyForNotifications) {
|
|
139
|
+
response.writeHead(503)
|
|
140
|
+
response.end('channel_not_ready')
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let body = ''
|
|
145
|
+
for await (const chunk of request) {
|
|
146
|
+
body += chunk.toString()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const turnId = String(request.headers['x-turn-id'] || '').trim()
|
|
150
|
+
const notification = {
|
|
151
|
+
jsonrpc: '2.0',
|
|
152
|
+
method: 'notifications/claude/channel',
|
|
153
|
+
params: {
|
|
154
|
+
content: body,
|
|
155
|
+
meta: {
|
|
156
|
+
lane,
|
|
157
|
+
turn_id: turnId,
|
|
158
|
+
method: request.method,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
writeMessage(notification)
|
|
164
|
+
await updateState({ status: 'ready', last_message_at: new Date().toISOString(), last_turn_id: turnId || null })
|
|
165
|
+
await appendLog({ type: 'notification', turn_id: turnId || null, body })
|
|
166
|
+
response.writeHead(200)
|
|
167
|
+
response.end('ok')
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
server.listen(port, '127.0.0.1', async () => {
|
|
171
|
+
await updateState({ status: 'listening' })
|
|
172
|
+
await appendLog({ type: 'listening' })
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
async function shutdown(code) {
|
|
176
|
+
await updateState({ status: 'closed' })
|
|
177
|
+
server.close(() => {
|
|
178
|
+
process.exit(code)
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
process.on('SIGINT', () => {
|
|
183
|
+
void shutdown(0)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
process.on('SIGTERM', () => {
|
|
187
|
+
void shutdown(0)
|
|
188
|
+
})
|