diff --git a/README.md b/README.md index 586b27e..1f4831f 100644 --- a/README.md +++ b/README.md @@ -124,19 +124,19 @@ Other built-in real-model templates: ```bash nightshift init --template real-simple --root bookmarks-demo nightshift init --template real-long-running --root incident-service -nightshift init --template tutorial-pastebin --root nightshift-pastebin +nightshift init --template tutorial-deaddrop --root nightshift-deaddrop ``` Create an isolated integration sandbox for a template: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin +python -m nightshift.cli integ-run --template tutorial-deaddrop ``` To create the sandbox and run the Python setup immediately: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin --setup +python -m nightshift.cli integ-run --template tutorial-deaddrop --setup ``` Then run the Python project setup helper. It finds the generated venv, installs this NightShift checkout into it, installs the target project, installs pytest by default, and runs `nightshift validate`: @@ -387,7 +387,7 @@ Additional docs: - [Quickstart](QUICKSTART.md) - [Tutorial 01: imageboard with real local models](examples/tutorial/01-imageboard/README.md) - [Tutorial 02: Lisp with real local models](examples/tutorial/02-lisp/README.md) -- [Tutorial 03: Pastebin with model fallback and telemetry](examples/tutorial/03-pastebin/README.md) +- [Tutorial 03: DeadDrop with fixed tests and telemetry](examples/tutorial/03-deaddrop/README.md) - [Config reference](docs/config-reference.md) - [Artifact review workflow](docs/artifact-review.md) - [Troubleshooting](docs/troubleshooting.md) diff --git a/docs/config-reference.md b/docs/config-reference.md index 97d787d..8a6687a 100644 --- a/docs/config-reference.md +++ b/docs/config-reference.md @@ -147,13 +147,13 @@ Supported fixture types are `png`, `jpg`, `json`, `sqlite`, `text`, and `blob`. Create a local integration sandbox from the NightShift repository root: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin +python -m nightshift.cli integ-run --template tutorial-deaddrop ``` Create, set up, validate, and run one task from the generated project directory: ```bash -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-001 +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-001 ``` Set up the generated Python project: @@ -185,9 +185,9 @@ python -m nightshift.cli integ-report --latest To clean up old sandboxes before creating a new one, keep only the newest three existing runs: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin --keep 3 +python -m nightshift.cli integ-run --template tutorial-deaddrop --keep 3 ``` -## Pastebin Tutorial +## DeadDrop Tutorial -`nightshift init --template tutorial-pastebin` creates a small Flask snippet-hosting target with deterministic tests and incremental NightShift tasks. Its pipeline includes semantic context retrieval, telemetry, debugger support, fixed task-specific tests, and a single default `qwen3-coder:30b` model path. +`nightshift init --template tutorial-deaddrop` creates a small Flask snippet sharing utility with deterministic tests and incremental NightShift tasks. Its pipeline includes semantic context retrieval, telemetry, debugger support, fixed task-specific tests, and a single default `qwen3-coder:30b` model path. diff --git a/docs/design.md b/docs/design.md index af143d3..44099c9 100644 --- a/docs/design.md +++ b/docs/design.md @@ -344,17 +344,17 @@ because: ```text PLAN - ↓ + ↓ REVIEW_PLAN - ↓ + ↓ IMPLEMENT - ↓ + ↓ TEST - ↓ + ↓ STATIC_ANALYSIS - ↓ + ↓ REVIEW - ↓ + ↓ DECISION ``` @@ -693,11 +693,11 @@ Validation occurs in multiple stages: ```text Tests - ↓ + ↓ Static Analysis - ↓ + ↓ Review Agent - ↓ + ↓ Decision ``` @@ -897,7 +897,7 @@ NightShift currently provides: * Final task notes, stage summaries, task completion artifacts, and run summaries * Documentation for config, artifact review, troubleshooting, quickstart, and patch workflows * A complete fake-agent patch-mode quickstart Lisp example under `examples/quickstart-lisp/` -* A deterministic pastebin tutorial template with model fallback configuration +* A deterministic DeadDrop tutorial template with fixed-test configuration The system remains sequential and local-first. It is designed to produce reviewable artifacts and repository state, not to deploy, push, or autonomously ship changes. @@ -1181,19 +1181,19 @@ Acceptance Criteria: - Includes tests for retrieval quality -- [x] TASK-015: Pastebin tutorial project template +- [x] TASK-015: DeadDrop tutorial project template Dependencies: - TASK-008 - TASK-005 Description: -Add a new tutorial project template for NightShift based on a small Pastebin/snippet-hosting service. This should work like the existing imageboard tutorial, but be simpler, more deterministic, and easier to use for testing agent orchestration. The template should be creatable with `--template`. +Add a new tutorial project template for NightShift based on a small DeadDrop snippet sharing utility. This should work like the existing imageboard tutorial, but be simpler, more deterministic, and easier to use for testing agent orchestration. The template should be creatable with `--template`. Acceptance Criteria: -- Adds a new template named `pastebin` +- Adds a new template named `deaddrop` - Supports creating the tutorial project with a command such as: - - `nightshift init --template tutorial-pastebin` + - `nightshift init --template tutorial-deaddrop` - Template includes a small but realistic app with: - snippet creation - snippet viewing @@ -1206,13 +1206,13 @@ Acceptance Criteria: - Uses deterministic fixtures and simple dependencies - Includes clear task descriptions for the agent to complete - Includes README instructions explaining the tutorial goals -- Supports model fallback ordering for this template: +- Supports single-model fixed-test flow for this template: - `qwen2.5-coder:14b` - `carstenuhlig/omnicoder-9b` - `deepseek-coder-v2:16b` - If the first model fails or exceeds its retry budget, the next fallback model is attempted - Records which model handled each attempt -- Includes tests for template creation and model fallback configuration +- Includes tests for template creation and fixed-test configuration --- # 17. Current Product Shape diff --git a/docs/future_ideas.md b/docs/future_ideas.md index 342bc81..b0d8789 100644 --- a/docs/future_ideas.md +++ b/docs/future_ideas.md @@ -12,6 +12,6 @@ Not to implement until we get successful long running runs. * maybe this is later ## A way to easily make A/B tests to benchmark models? -* Right now I can do this manually, for example I want to run the tutorial-pastebin with qwen3.6:27b as the planner and qwen2.5-coder:14b as the coder, and another with qwen3.6:27b as both, etc. +* Right now I can do this manually, for example I want to run the tutorial-deaddrop with qwen3.6:27b as the planner and qwen2.5-coder:14b as the coder, and another with qwen3.6:27b as both, etc. * Maybe there is a way to make it easier to do that, possibly by creating a template that can be controlled by a larger multi-run file? * This is probably for way later. diff --git a/docs/ideas.md b/docs/ideas.md index 6015575..848c6c2 100644 --- a/docs/ideas.md +++ b/docs/ideas.md @@ -14,7 +14,7 @@ Status: implemented. Implemented command: ```powershell -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-001 +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-001 ``` It creates the integration sandbox, sets up the venv, runs validation through setup, runs the task from the generated project directory, and prints the artifact root. Use `--dry-run` to preview the setup and task command. @@ -24,7 +24,7 @@ Running integration tests is still too manual. Current process: - install the current version of NightShift -- run `python -m nightshift.cli integ-run --template tutorial-pastebin --setup` +- run `python -m nightshift.cli integ-run --template tutorial-deaddrop --setup` - copy the activation line from the output and run it - `cd` into the generated directory - run the task there, because running from the repo root does not find `nightshift.yaml` @@ -34,7 +34,7 @@ Recommendation: implement a wrapper command, not just a loose script. Target command: ```powershell -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-001 +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-001 ``` It should: @@ -49,34 +49,34 @@ It should: Useful variants: ```powershell -python -m nightshift.cli integ-test --template tutorial-pastebin --all -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-002 --keep 3 +python -m nightshift.cli integ-test --template tutorial-deaddrop --all +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-002 --keep 3 ``` The base-directory config issue may not be a core bug, but it is bad UX. The wrapper should handle `cwd` correctly. -## P0/P1: Remove Multi-Candidate Workflow From Default Pastebin +## P0/P1: Remove Multi-Candidate Workflow From Default DeadDrop -Status: implemented for the default pastebin template and tutorial example. +Status: implemented for the default DeadDrop template and tutorial example. Original idea: - The multi-candidate workflow does not add as much as expected. - Keep it as an example, maybe `example-multiagent`. -Recommendation: yes. Remove it from the default pastebin tutorial. +Recommendation: yes. Remove it from the default DeadDrop tutorial. Reason: -- Pastebin is becoming the reliability harness. +- DeadDrop is becoming the reliability harness. - Multi-candidate fallback makes artifacts harder to reason about. - It adds model variability while we are still debugging pipeline behavior. Better split: ```text -tutorial-pastebin -tutorial-pastebin-multiagent +tutorial-deaddrop +tutorial-deaddrop-multiagent ``` or: @@ -85,7 +85,7 @@ or: examples/templates/multiagent-fallback ``` -Default pastebin should be boring: +Default DeadDrop should be boring: ```text planner -> semantic_context -> context -> implement -> validate -> test -> review @@ -93,9 +93,9 @@ planner -> semantic_context -> context -> implement -> validate -> test -> revie Use one strong implementer first. Add fallback only in a separate experiment template. -## P1: Add A Qwen3 / 30B Pastebin Variant +## P1: Add A Qwen3 / 30B DeadDrop Variant -Status: implemented as the default pastebin model path using `qwen3-coder:30b`. +Status: implemented as the default DeadDrop model path using `qwen3-coder:30b`. Original idea: @@ -110,7 +110,7 @@ kass reply- No lets make this the default. the qwen3-coder:30b is fast now for m Suggested template/config: ```text -tutorial-pastebin-qwen3 +tutorial-deaddrop-qwen3 ``` Possible role split: @@ -188,7 +188,7 @@ Original idea: - Have a test governance layer for when agents write tests. - A reviewer validates alignment with acceptance criteria. -Recommendation: yes, but only for generated-test mode. Do not put generated tests back into default pastebin yet. +Recommendation: yes, but only for generated-test mode. Do not put generated tests back into default DeadDrop yet. The previous failures proved test-writing agents will: @@ -240,7 +240,7 @@ Do not modify: - tests/test_task001.py ``` -This may help smaller models, but it is another model output that can be wrong. Add it only after the fixed-test pipeline works through all pastebin tasks. +This may help smaller models, but it is another model output that can be wrong. Add it only after the fixed-test pipeline works through all DeadDrop tasks. ## P2/P3: Add A Test Planner @@ -267,7 +267,7 @@ test_planner -> write_tests -> test_governance -> implement For now, fold this idea into the future test governance/analyzer work. -## P1: Add Fixed Tests For All Pastebin Tasks +## P1: Add Fixed Tests For All DeadDrop Tasks Status: mostly implemented in the template. diff --git a/examples/tutorial/03-pastebin/README.md b/examples/tutorial/03-deaddrop/README.md similarity index 81% rename from examples/tutorial/03-pastebin/README.md rename to examples/tutorial/03-deaddrop/README.md index ec07888..094108a 100644 --- a/examples/tutorial/03-pastebin/README.md +++ b/examples/tutorial/03-deaddrop/README.md @@ -1,6 +1,6 @@ -# Tutorial 03: Pastebin With Fixed Tests And Telemetry +# Tutorial 03: DeadDrop With Fixed Tests And Telemetry -This tutorial uses the `tutorial-pastebin` template: a small Flask snippet-hosting service designed for deterministic NightShift orchestration tests. +This tutorial uses the `tutorial-deaddrop` template: a small Flask snippet sharing utility designed for deterministic NightShift orchestration tests. It is intentionally simpler than the imageboard tutorial. There are no uploads, thumbnails, sessions, or moderation queues. The work is ordinary web-app behavior: snippet creation, viewing, listing, filtering, expiration handling, and simple HTML forms. @@ -9,26 +9,26 @@ It is intentionally simpler than the imageboard tutorial. There are no uploads, Run this from a disposable parent directory: ```bash -nightshift init --template tutorial-pastebin --root nightshift-pastebin -cd nightshift-pastebin +nightshift init --template tutorial-deaddrop --root nightshift-deaddrop +cd nightshift-deaddrop ``` For an isolated local integration run, use the integration sandbox command from the NightShift repository root: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin +python -m nightshift.cli integ-run --template tutorial-deaddrop ``` To create, set up, validate, and run one task in a single command: ```bash -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-001 +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-001 ``` To create the sandbox and set up the Python project immediately: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin --setup +python -m nightshift.cli integ-run --template tutorial-deaddrop --setup ``` Then set up the generated Python project: @@ -56,7 +56,7 @@ nightshift.yaml reviewer.md tasks.md src/ - pastebin_app/ + deaddrop_app/ templates/ tests/ pyproject.toml @@ -79,7 +79,7 @@ Install target dependencies: python -m pip install -e . pytest flask ``` -Install and start Ollama, then pull the default pastebin model: +Install and start Ollama, then pull the default DeadDrop model: ```bash ollama pull qwen3-coder:30b @@ -90,11 +90,11 @@ NightShift uses Ollama's local HTTP API, normally at `http://localhost:11434`. ## Model -The default pastebin pipeline uses one strong local coder model: +The default DeadDrop pipeline uses one strong local coder model: - `qwen3-coder:30b` -NightShift records which agent/model handled each stage in `telemetry-summary.md`. Multi-candidate fallback belongs in a separate experiment template, not the default pastebin reliability harness. +NightShift records which agent/model handled each stage in `telemetry-summary.md`. Multi-candidate fallback belongs in a separate experiment template, not the default DeadDrop reliability harness. ## TDD Pipeline @@ -137,4 +137,4 @@ Then inspect: ## Pipeline Reference -A copy of the template pipeline is included here as [nightshift.yaml](nightshift.yaml). The canonical runnable template lives under `nightshift/project_templates/tutorial-pastebin/`. +A copy of the template pipeline is included here as [nightshift.yaml](nightshift.yaml). The canonical runnable template lives under `nightshift/project_templates/tutorial-deaddrop/`. diff --git a/examples/tutorial/03-pastebin/nightshift.yaml b/examples/tutorial/03-deaddrop/nightshift.yaml similarity index 98% rename from examples/tutorial/03-pastebin/nightshift.yaml rename to examples/tutorial/03-deaddrop/nightshift.yaml index 871ebf5..f5ca2eb 100644 --- a/examples/tutorial/03-pastebin/nightshift.yaml +++ b/examples/tutorial/03-deaddrop/nightshift.yaml @@ -1,5 +1,5 @@ project: - name: pastebin + name: deaddrop root: . task_file: .nightshift/tasks.md artifact_dir: .nightshift @@ -20,7 +20,7 @@ safety: - curl | bash experiment: - label: pastebin-qwen3-coder + label: deaddrop-qwen3-coder prompt_variant: fixed-tests-qwen3-coder-30b-v1 agents: diff --git a/examples/tutorial/03-pastebin/tasks.md b/examples/tutorial/03-deaddrop/tasks.md similarity index 91% rename from examples/tutorial/03-pastebin/tasks.md rename to examples/tutorial/03-deaddrop/tasks.md index ffd85a0..20ba925 100644 --- a/examples/tutorial/03-pastebin/tasks.md +++ b/examples/tutorial/03-deaddrop/tasks.md @@ -1,9 +1,9 @@ -# Pastebin Tutorial Tasks +# DeadDrop Tutorial Tasks - [ ] TASK-001: Snippet creation and viewing Description: -Complete the pastebin service foundation. Support creating snippets with title and body. Support viewing a single snippet by id. +Complete the snippet sharing utility foundation. Support creating snippets with title and body. Support viewing a single snippet by id. Acceptance Criteria: - POST `/snippets` creates a snippet with title and body diff --git a/nightshift/cli.py b/nightshift/cli.py index 859d0e6..7dff729 100644 --- a/nightshift/cli.py +++ b/nightshift/cli.py @@ -115,7 +115,7 @@ def build_parser() -> argparse.ArgumentParser: integ_test_parser.add_argument("--root", default=".", help="Repository root where integ_runs/ is created.") integ_test_parser.add_argument( "--template", - default="tutorial-pastebin", + default="tutorial-deaddrop", choices=available_templates(), help="Template to initialize inside the sandbox.", ) diff --git a/nightshift/integ_test.py b/nightshift/integ_test.py index d9b355e..9d6df74 100644 --- a/nightshift/integ_test.py +++ b/nightshift/integ_test.py @@ -23,7 +23,7 @@ class IntegrationTestResult: def run_integration_test( root: str | Path = ".", *, - template: str = "tutorial-pastebin", + template: str = "tutorial-deaddrop", task: str | None = None, all_tasks: bool = False, keep: int | None = None, diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/debugger.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/debugger.md similarity index 90% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/agents/debugger.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/debugger.md index 8d6a542..7ffd81b 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/debugger.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/debugger.md @@ -1,4 +1,4 @@ -You are the debugger agent for the NightShift pastebin tutorial. +You are the debugger agent for the NightShift DeadDrop tutorial. Diagnose failed attempts without editing files. Distinguish fixed-test/template problems from implementation bugs. diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/implementer.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/implementer.md similarity index 92% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/agents/implementer.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/implementer.md index e7416fe..8df3c39 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/implementer.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/implementer.md @@ -1,11 +1,11 @@ -You are the implementation agent for the NightShift pastebin tutorial. +You are the implementation agent for the NightShift DeadDrop tutorial. Implement the smallest application change that satisfies the current task and the generated tests. Do not rewrite generated tests unless the retry context explicitly says they are inaccurate. Do not edit files under `tests/`. The tutorial tests are fixed; make the application satisfy them. Do not add behavior for future tasks unless needed to satisfy the current tests. Use Flask and `sqlite3` from the Python standard library. Do not use SQLAlchemy, Flask-SQLAlchemy, or undeclared dependencies. -Keep the public package name `pastebin_app`. +Keep the public package name `deaddrop_app`. Keep the public app entry point `create_app(database_path: str | None = None)`. Respect `database_path`; do not hard-code `snippets.db` when a database path is supplied. Tests should interact through HTTP routes and `create_app`, not through ORM/session globals. diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/planner.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/planner.md similarity index 85% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/agents/planner.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/planner.md index 32b3210..20aa71b 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/planner.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/planner.md @@ -1,4 +1,4 @@ -You are the planning agent for the NightShift pastebin tutorial. +You are the planning agent for the NightShift DeadDrop tutorial. Create a concise TDD implementation plan for the current task. @@ -9,7 +9,7 @@ Plan in this order: If repository context is needed, request it with lookup_requests. Prefer small edits and deterministic tests. -Use the actual package and files from repository context. For this tutorial the public app entry point is `pastebin_app.app:create_app`. +Use the actual package and files from repository context. For this tutorial the public app entry point is `deaddrop_app.app:create_app`. Do not assume top-level modules such as `app`, `models`, `routes`, or `main` exist. Do not propose SQLAlchemy, Flask-SQLAlchemy, or ORM globals. Use Flask plus `sqlite3` from the Python standard library. Do not propose tests that import `session`, `Snippet`, `engine`, or other implementation internals. diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/reviewer.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/reviewer.md similarity index 92% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/agents/reviewer.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/reviewer.md index b6e940e..3ef9120 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/reviewer.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/reviewer.md @@ -1,4 +1,4 @@ -You are the review agent for the NightShift pastebin tutorial. +You are the review agent for the NightShift DeadDrop tutorial. When reviewing generated tests, check that they map only to the current task acceptance criteria and do not require future-task behavior. When reviewing implementation, check that the change is small, deterministic, and satisfies the generated tests without unrelated rewrites. diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/test-writer.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/test-writer.md similarity index 83% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/agents/test-writer.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/test-writer.md index c4bdbaf..1635d0f 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/agents/test-writer.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/agents/test-writer.md @@ -1,4 +1,4 @@ -You are the test-writing agent for the NightShift pastebin tutorial. +You are the test-writing agent for the NightShift DeadDrop tutorial. Write only tests for the current task's acceptance criteria. Do not implement application code. @@ -14,8 +14,8 @@ Use one fenced block per file: Prefer pytest tests that describe the public behavior from the task. Keep tests deterministic and isolated with temporary databases or temporary paths. -Use the existing package name `pastebin_app`. +Use the existing package name `deaddrop_app`. Import only the public app factory: -`from pastebin_app.app import create_app` +`from deaddrop_app.app import create_app` Do not import `app`, `session`, `Snippet`, `engine`, `models`, or top-level modules. Do not use SQLAlchemy or require undeclared dependencies. diff --git a/nightshift/project_templates/tutorial-pastebin/.nightshift/tasks.md b/nightshift/project_templates/tutorial-deaddrop/.nightshift/tasks.md similarity index 91% rename from nightshift/project_templates/tutorial-pastebin/.nightshift/tasks.md rename to nightshift/project_templates/tutorial-deaddrop/.nightshift/tasks.md index ffd85a0..20ba925 100644 --- a/nightshift/project_templates/tutorial-pastebin/.nightshift/tasks.md +++ b/nightshift/project_templates/tutorial-deaddrop/.nightshift/tasks.md @@ -1,9 +1,9 @@ -# Pastebin Tutorial Tasks +# DeadDrop Tutorial Tasks - [ ] TASK-001: Snippet creation and viewing Description: -Complete the pastebin service foundation. Support creating snippets with title and body. Support viewing a single snippet by id. +Complete the snippet sharing utility foundation. Support creating snippets with title and body. Support viewing a single snippet by id. Acceptance Criteria: - POST `/snippets` creates a snippet with title and body diff --git a/nightshift/project_templates/tutorial-pastebin/README.md b/nightshift/project_templates/tutorial-deaddrop/README.md similarity index 75% rename from nightshift/project_templates/tutorial-pastebin/README.md rename to nightshift/project_templates/tutorial-deaddrop/README.md index 3999b9c..6c9de41 100644 --- a/nightshift/project_templates/tutorial-pastebin/README.md +++ b/nightshift/project_templates/tutorial-deaddrop/README.md @@ -1,29 +1,29 @@ -# NightShift Pastebin Tutorial +# NightShift DeadDrop Tutorial -This template is a small deterministic snippet-hosting service for testing NightShift orchestration. +This template is a small deterministic snippet sharing utility for testing NightShift orchestration. Create it with: ```bash -nightshift init --template tutorial-pastebin +nightshift init --template tutorial-deaddrop ``` Or create an isolated integration sandbox from the NightShift repository root: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin +python -m nightshift.cli integ-run --template tutorial-deaddrop ``` To create, set up, validate, and run one task in a single command: ```bash -python -m nightshift.cli integ-test --template tutorial-pastebin --task TASK-001 +python -m nightshift.cli integ-test --template tutorial-deaddrop --task TASK-001 ``` To create the sandbox and set it up in one step: ```bash -python -m nightshift.cli integ-run --template tutorial-pastebin --setup +python -m nightshift.cli integ-run --template tutorial-deaddrop --setup ``` Then set up the generated Python project: @@ -54,7 +54,7 @@ nightshift what-happened When running from an integration sandbox, the same commands are run inside `integ_runs//project`. -The default pastebin pipeline uses `qwen3-coder:30b` for planning, implementation, debugging, test review, and final review. It intentionally does not use multi-candidate fallback; pastebin is the deterministic reliability harness. +The default DeadDrop pipeline uses `qwen3-coder:30b` for planning, implementation, debugging, test review, and final review. It intentionally does not use multi-candidate fallback; DeadDrop is the deterministic reliability harness. Telemetry artifacts record which agent/model handled each stage and estimate token usage. diff --git a/nightshift/project_templates/tutorial-pastebin/nightshift.yaml b/nightshift/project_templates/tutorial-deaddrop/nightshift.yaml similarity index 98% rename from nightshift/project_templates/tutorial-pastebin/nightshift.yaml rename to nightshift/project_templates/tutorial-deaddrop/nightshift.yaml index 871ebf5..f5ca2eb 100644 --- a/nightshift/project_templates/tutorial-pastebin/nightshift.yaml +++ b/nightshift/project_templates/tutorial-deaddrop/nightshift.yaml @@ -1,5 +1,5 @@ project: - name: pastebin + name: deaddrop root: . task_file: .nightshift/tasks.md artifact_dir: .nightshift @@ -20,7 +20,7 @@ safety: - curl | bash experiment: - label: pastebin-qwen3-coder + label: deaddrop-qwen3-coder prompt_variant: fixed-tests-qwen3-coder-30b-v1 agents: diff --git a/nightshift/project_templates/tutorial-pastebin/pyproject.toml b/nightshift/project_templates/tutorial-deaddrop/pyproject.toml similarity index 89% rename from nightshift/project_templates/tutorial-pastebin/pyproject.toml rename to nightshift/project_templates/tutorial-deaddrop/pyproject.toml index 53f2a2f..974ec4f 100644 --- a/nightshift/project_templates/tutorial-pastebin/pyproject.toml +++ b/nightshift/project_templates/tutorial-deaddrop/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=69"] build-backend = "setuptools.build_meta" [project] -name = "nightshift-pastebin-target" +name = "nightshift-deaddrop-target" version = "0.1.0" requires-python = ">=3.11" dependencies = ["flask"] diff --git a/nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/__init__.py b/nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/__init__.py new file mode 100644 index 0000000..7fd03e0 --- /dev/null +++ b/nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/__init__.py @@ -0,0 +1 @@ +"""DeadDrop package for the NightShift tutorial.""" diff --git a/nightshift/project_templates/tutorial-pastebin/src/pastebin_app/app.py b/nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/app.py similarity index 82% rename from nightshift/project_templates/tutorial-pastebin/src/pastebin_app/app.py rename to nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/app.py index e1f5418..6e35aa2 100644 --- a/nightshift/project_templates/tutorial-pastebin/src/pastebin_app/app.py +++ b/nightshift/project_templates/tutorial-deaddrop/src/deaddrop_app/app.py @@ -1,4 +1,4 @@ -"""Pastebin tutorial application scaffold.""" +"""DeadDrop tutorial application scaffold.""" from __future__ import annotations diff --git a/nightshift/project_templates/tutorial-pastebin/templates/.gitkeep b/nightshift/project_templates/tutorial-deaddrop/templates/.gitkeep similarity index 100% rename from nightshift/project_templates/tutorial-pastebin/templates/.gitkeep rename to nightshift/project_templates/tutorial-deaddrop/templates/.gitkeep diff --git a/nightshift/project_templates/tutorial-pastebin/tests/.gitkeep b/nightshift/project_templates/tutorial-deaddrop/tests/.gitkeep similarity index 100% rename from nightshift/project_templates/tutorial-pastebin/tests/.gitkeep rename to nightshift/project_templates/tutorial-deaddrop/tests/.gitkeep diff --git a/nightshift/project_templates/tutorial-pastebin/tests/test_task001.py b/nightshift/project_templates/tutorial-deaddrop/tests/test_task001.py similarity index 96% rename from nightshift/project_templates/tutorial-pastebin/tests/test_task001.py rename to nightshift/project_templates/tutorial-deaddrop/tests/test_task001.py index b72ec4b..a1434ce 100644 --- a/nightshift/project_templates/tutorial-pastebin/tests/test_task001.py +++ b/nightshift/project_templates/tutorial-deaddrop/tests/test_task001.py @@ -1,4 +1,4 @@ -from pastebin_app.app import create_app +from deaddrop_app.app import create_app def test_create_snippet_returns_created_snippet_id(tmp_path): diff --git a/nightshift/project_templates/tutorial-pastebin/tests/test_task002.py b/nightshift/project_templates/tutorial-deaddrop/tests/test_task002.py similarity index 97% rename from nightshift/project_templates/tutorial-pastebin/tests/test_task002.py rename to nightshift/project_templates/tutorial-deaddrop/tests/test_task002.py index dfe6950..0b0499d 100644 --- a/nightshift/project_templates/tutorial-pastebin/tests/test_task002.py +++ b/nightshift/project_templates/tutorial-deaddrop/tests/test_task002.py @@ -1,4 +1,4 @@ -from pastebin_app.app import create_app +from deaddrop_app.app import create_app def test_create_snippet_accepts_optional_metadata(tmp_path): diff --git a/nightshift/project_templates/tutorial-pastebin/tests/test_task003.py b/nightshift/project_templates/tutorial-deaddrop/tests/test_task003.py similarity index 97% rename from nightshift/project_templates/tutorial-pastebin/tests/test_task003.py rename to nightshift/project_templates/tutorial-deaddrop/tests/test_task003.py index 33656f1..09f8d85 100644 --- a/nightshift/project_templates/tutorial-pastebin/tests/test_task003.py +++ b/nightshift/project_templates/tutorial-deaddrop/tests/test_task003.py @@ -1,4 +1,4 @@ -from pastebin_app.app import create_app +from deaddrop_app.app import create_app def _create(client, title, body, **metadata): diff --git a/nightshift/project_templates/tutorial-pastebin/tests/test_task004.py b/nightshift/project_templates/tutorial-deaddrop/tests/test_task004.py similarity index 97% rename from nightshift/project_templates/tutorial-pastebin/tests/test_task004.py rename to nightshift/project_templates/tutorial-deaddrop/tests/test_task004.py index e6471bf..1c31548 100644 --- a/nightshift/project_templates/tutorial-pastebin/tests/test_task004.py +++ b/nightshift/project_templates/tutorial-deaddrop/tests/test_task004.py @@ -1,4 +1,4 @@ -from pastebin_app.app import create_app +from deaddrop_app.app import create_app def test_expired_snippets_are_excluded_from_listing(tmp_path): diff --git a/nightshift/project_templates/tutorial-pastebin/tests/test_task005.py b/nightshift/project_templates/tutorial-deaddrop/tests/test_task005.py similarity index 96% rename from nightshift/project_templates/tutorial-pastebin/tests/test_task005.py rename to nightshift/project_templates/tutorial-deaddrop/tests/test_task005.py index dba7a8f..c20e7f0 100644 --- a/nightshift/project_templates/tutorial-pastebin/tests/test_task005.py +++ b/nightshift/project_templates/tutorial-deaddrop/tests/test_task005.py @@ -1,4 +1,4 @@ -from pastebin_app.app import create_app +from deaddrop_app.app import create_app def test_root_shows_snippet_list_html(tmp_path): diff --git a/nightshift/project_templates/tutorial-pastebin/src/pastebin_app/__init__.py b/nightshift/project_templates/tutorial-pastebin/src/pastebin_app/__init__.py deleted file mode 100644 index 8a89423..0000000 --- a/nightshift/project_templates/tutorial-pastebin/src/pastebin_app/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Pastebin package for the NightShift tutorial.""" diff --git a/tests/test_init.py b/tests/test_init.py index 1724050..98939ab 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -59,22 +59,22 @@ class InitProjectTests(unittest.TestCase): self.assertIn("real-long-running", available_templates()) self.assertIn("real-simple", available_templates()) self.assertIn("tutorial-imageboard", available_templates()) - self.assertIn("tutorial-pastebin", available_templates()) + self.assertIn("tutorial-deaddrop", available_templates()) - def test_init_pastebin_template_creates_skeleton_and_qwen3_config(self) -> None: + def test_init_DeadDrop_template_creates_skeleton_and_qwen3_config(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) - init_project(root, template="tutorial-pastebin") + init_project(root, template="tutorial-deaddrop") config = (root / "nightshift.yaml").read_text(encoding="utf-8") self.assertTrue((root / ".nightshift" / "tasks.md").exists()) self.assertTrue((root / ".nightshift" / "agents" / "test-writer.md").exists()) - self.assertTrue((root / "src" / "pastebin_app" / "app.py").exists()) + self.assertTrue((root / "src" / "deaddrop_app" / "app.py").exists()) self.assertTrue((root / "tests" / "test_task001.py").exists()) self.assertTrue((root / "tests" / ".gitkeep").exists()) - self.assertFalse((root / "tests" / "test_pastebin.py").exists()) - self.assertIn("def create_app(database_path", (root / "src" / "pastebin_app" / "app.py").read_text(encoding="utf-8")) + self.assertFalse((root / "tests" / "test_deaddrop.py").exists()) + self.assertIn("def create_app(database_path", (root / "src" / "deaddrop_app" / "app.py").read_text(encoding="utf-8")) self.assertIn("type: semantic_context", config) self.assertNotIn("id: write_tests", config) self.assertNotIn("id: review_tests", config) @@ -88,15 +88,15 @@ class InitProjectTests(unittest.TestCase): self.assertNotIn("carstenuhlig/omnicoder-9b", config) self.assertNotIn("deepseek-coder-v2:16b", config) - def test_pastebin_example_tutorial_docs_exist(self) -> None: + def test_deaddrop_example_tutorial_docs_exist(self) -> None: root = Path(__file__).resolve().parents[1] - tutorial = root / "examples" / "tutorial" / "03-pastebin" + tutorial = root / "examples" / "tutorial" / "03-deaddrop" self.assertTrue((tutorial / "README.md").exists()) self.assertTrue((tutorial / "tasks.md").exists()) self.assertTrue((tutorial / "nightshift.yaml").exists()) self.assertIn( - "nightshift init --template tutorial-pastebin", + "nightshift init --template tutorial-deaddrop", (tutorial / "README.md").read_text(encoding="utf-8"), ) diff --git a/tests/test_integ_setup.py b/tests/test_integ_setup.py index f779f52..2e322cf 100644 --- a/tests/test_integ_setup.py +++ b/tests/test_integ_setup.py @@ -11,7 +11,7 @@ class IntegrationSetupTests(unittest.TestCase): def test_setup_python_project_dry_run_uses_integration_venv(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) - run = create_integration_run(root, template="tutorial-pastebin") + run = create_integration_run(root, template="tutorial-deaddrop") result = setup_python_project( run.directory / "project", @@ -48,7 +48,7 @@ class IntegrationSetupTests(unittest.TestCase): def test_format_setup_result_includes_activation_hint(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) - run = create_integration_run(root, template="tutorial-pastebin") + run = create_integration_run(root, template="tutorial-deaddrop") result = setup_python_project( run.directory / "project", diff --git a/tests/test_integ_test.py b/tests/test_integ_test.py index 803c8f2..ca44947 100644 --- a/tests/test_integ_test.py +++ b/tests/test_integ_test.py @@ -11,7 +11,7 @@ class IntegrationTestCommandTests(unittest.TestCase): with tempfile.TemporaryDirectory() as directory: result = run_integration_test( directory, - template="tutorial-pastebin", + template="tutorial-deaddrop", task="TASK-001", dry_run=True, ) diff --git a/tests/test_reliability_features.py b/tests/test_reliability_features.py index fbe46e9..930c9bc 100644 --- a/tests/test_reliability_features.py +++ b/tests/test_reliability_features.py @@ -30,14 +30,14 @@ class ReliabilityFeatureTests(unittest.TestCase): "\n".join( [ "ImportError while importing test module 'tests/test_app.py'.", - "ModuleNotFoundError: No module named 'pastebin_app'", + "ModuleNotFoundError: No module named 'deaddrop_app'", ] ), exit_code=2, ) self.assertEqual(result.category, "missing dependency") - self.assertIn("pastebin_app", result.probable_root_cause) + self.assertIn("deaddrop_app", result.probable_root_cause) def test_failure_classifier_detects_local_import_mismatch(self) -> None: result = classify_failure( @@ -75,7 +75,7 @@ class ReliabilityFeatureTests(unittest.TestCase): result = classify_failure( "\n".join( [ - ' File "C:\\repo\\project\\src\\pastebin_app\\app.py", line 31, in get_db', + ' File "C:\\repo\\project\\src\\deaddrop_app\\app.py", line 31, in get_db', " if 'db' not in g:", "NameError: name 'g' is not defined", ] @@ -84,7 +84,7 @@ class ReliabilityFeatureTests(unittest.TestCase): ) self.assertEqual(result.category, "logic bug") - self.assertIn("src\\pastebin_app\\app.py", result.probable_root_cause) + self.assertIn("src\\deaddrop_app\\app.py", result.probable_root_cause) def test_retry_churn_stops_on_repeated_failure_signature(self) -> None: entries = ( @@ -94,7 +94,7 @@ class ReliabilityFeatureTests(unittest.TestCase): status="fail", cause="Command exited with code 1: python -m pytest -q", next_stage="implement", - failure_signature="NameError | src/pastebin_app/app.py | 31 | python -m pytest -q", + failure_signature="NameError | src/deaddrop_app/app.py | 31 | python -m pytest -q", ), RetryMemoryEntry( attempt=2, @@ -102,7 +102,7 @@ class ReliabilityFeatureTests(unittest.TestCase): status="fail", cause="Command exited with code 1: python -m pytest -q", next_stage="implement", - failure_signature="NameError | src/pastebin_app/app.py | 31 | python -m pytest -q", + failure_signature="NameError | src/deaddrop_app/app.py | 31 | python -m pytest -q", ), ) @@ -119,7 +119,7 @@ class ReliabilityFeatureTests(unittest.TestCase): status="fail", cause="Command exited with code 1: python -m pytest -q", next_stage="implement", - failure_signature="NameError | src/pastebin_app/app.py | 31 | python -m pytest -q", + failure_signature="NameError | src/deaddrop_app/app.py | 31 | python -m pytest -q", ) for attempt in range(1, 4) ) @@ -132,7 +132,7 @@ class ReliabilityFeatureTests(unittest.TestCase): signature = build_failure_signature( "\n".join( [ - ' File "C:\\repo\\project\\src\\pastebin_app\\app.py", line 31, in get_db', + ' File "C:\\repo\\project\\src\\deaddrop_app\\app.py", line 31, in get_db', "NameError: name 'g' is not defined", ' File "C:\\Users\\metis\\...\\site-packages\\_pytest\\cacheprovider.py", line 429, in set', ] @@ -140,7 +140,7 @@ class ReliabilityFeatureTests(unittest.TestCase): reason="Command exited with code 1: python -m pytest -q", ) - self.assertIn("src\\pastebin_app\\app.py", signature) + self.assertIn("src\\deaddrop_app\\app.py", signature) self.assertNotIn("_pytest\\cacheprovider.py", signature) def test_command_failure_writes_diagnostics_and_retry_memory(self) -> None: diff --git a/tests/test_what_happened.py b/tests/test_what_happened.py index 40cff60..d1f0d72 100644 --- a/tests/test_what_happened.py +++ b/tests/test_what_happened.py @@ -32,7 +32,7 @@ class WhatHappenedTests(unittest.TestCase): encoding="utf-8", ) (task_dir / "test-output-1.txt").write_text( - "Command: `python -m pytest -q`\nExit code: 2\nModuleNotFoundError: No module named 'pastebin_app'\n", + "Command: `python -m pytest -q`\nExit code: 2\nModuleNotFoundError: No module named 'deaddrop_app'\n", encoding="utf-8", ) (diagnostics / "test-failure-retry-1.md").write_text(