devflow-toolkit 0.3.0__py3-none-any.whl

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.
Files changed (63) hide show
  1. devflow/__init__.py +0 -0
  2. devflow/adapters/__init__.py +47 -0
  3. devflow/adapters/agents.py +49 -0
  4. devflow/adapters/base.py +81 -0
  5. devflow/adapters/claude_code.py +120 -0
  6. devflow/adapters/codex.py +111 -0
  7. devflow/adapters/detector.py +118 -0
  8. devflow/adapters/instructions.py +263 -0
  9. devflow/adapters/kiro.py +211 -0
  10. devflow/adapters/opencode.py +237 -0
  11. devflow/adapters/registry.py +41 -0
  12. devflow/cli.py +39 -0
  13. devflow/commands/__init__.py +6 -0
  14. devflow/commands/approve.py +98 -0
  15. devflow/commands/harness.py +98 -0
  16. devflow/commands/init.py +544 -0
  17. devflow/commands/spec.py +514 -0
  18. devflow/commands/status.py +156 -0
  19. devflow/core/__init__.py +15 -0
  20. devflow/core/architecture.py +469 -0
  21. devflow/core/artifacts/__init__.py +29 -0
  22. devflow/core/artifacts/errors.py +19 -0
  23. devflow/core/artifacts/models.py +82 -0
  24. devflow/core/artifacts/store.py +130 -0
  25. devflow/core/clock.py +67 -0
  26. devflow/core/config.py +706 -0
  27. devflow/core/constitution.py +166 -0
  28. devflow/core/discovery.py +1304 -0
  29. devflow/core/ports.py +159 -0
  30. devflow/core/profile_manager.py +311 -0
  31. devflow/core/project.py +533 -0
  32. devflow/core/spec_workflow.py +932 -0
  33. devflow/core/specification.py +2443 -0
  34. devflow/core/state/__init__.py +75 -0
  35. devflow/core/state/errors.py +39 -0
  36. devflow/core/state/events.py +725 -0
  37. devflow/core/state/locator.py +116 -0
  38. devflow/core/state/lock.py +69 -0
  39. devflow/core/state/manager.py +960 -0
  40. devflow/core/state/models.py +164 -0
  41. devflow/core/state/transitions.py +114 -0
  42. devflow/models/__init__.py +6 -0
  43. devflow/models/profile.py +63 -0
  44. devflow/models/project.py +47 -0
  45. devflow/profiles/ai-rag/constitution/ai-rag-standards.md +49 -0
  46. devflow/profiles/ai-rag/profile.yaml +28 -0
  47. devflow/profiles/base/constitution/architecture.md +58 -0
  48. devflow/profiles/base/constitution/code-standards.md +85 -0
  49. devflow/profiles/base/constitution/constitution.md +85 -0
  50. devflow/profiles/base/profile.yaml +15 -0
  51. devflow/profiles/django-backend/constitution/django-standards.md +64 -0
  52. devflow/profiles/django-backend/profile.yaml +24 -0
  53. devflow/profiles/fastapi-backend/constitution/fastapi-standards.md +59 -0
  54. devflow/profiles/fastapi-backend/profile.yaml +23 -0
  55. devflow/prompts/__init__.py +200 -0
  56. devflow/prompts/discovery.md +119 -0
  57. devflow/prompts/spec.greenfield.md +149 -0
  58. devflow/prompts/spec.md +116 -0
  59. devflow_toolkit-0.3.0.dist-info/METADATA +628 -0
  60. devflow_toolkit-0.3.0.dist-info/RECORD +63 -0
  61. devflow_toolkit-0.3.0.dist-info/WHEEL +4 -0
  62. devflow_toolkit-0.3.0.dist-info/entry_points.txt +2 -0
  63. devflow_toolkit-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,628 @@
1
+ Metadata-Version: 2.5
2
+ Name: devflow-toolkit
3
+ Version: 0.3.0
4
+ Summary: Specification workflow toolkit for AI-assisted software changes
5
+ Author: DevFlow contributors
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: agents,ai,architecture,cli,greenfield,sdd,specification,workflow
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: MacOS
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Documentation
20
+ Classifier: Topic :: Software Development :: Documentation
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: pyyaml>=6.0
24
+ Requires-Dist: rich>=13.0
25
+ Requires-Dist: typer>=0.12
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.2; extra == 'dev'
28
+ Requires-Dist: pytest>=8.0; extra == 'dev'
29
+ Requires-Dist: ruff>=0.12; extra == 'dev'
30
+ Requires-Dist: twine>=5.0; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # DevFlow Toolkit
34
+
35
+ DevFlow is an installable command-line toolkit for managing
36
+ specification-driven changes in existing software projects with the help
37
+ of an AI coding agent.
38
+
39
+ It captures the project context, the project constitution and the
40
+ approval history, so a specification can be reviewed and approved before
41
+ anyone starts implementing it. DevFlow owns the workflow state; the
42
+ selected agent harness is only the execution backend that drafts the
43
+ specification.
44
+
45
+ This is the `0.3.0` MVP. It implements the **discovery and
46
+ specification stages only**. It supports two specification contexts:
47
+ **Existing Project** (the default) and **Greenfield**. It is not a
48
+ complete SDD platform and does not include planning, implementation or
49
+ review workflows.
50
+
51
+ Discovery decides whether a request is ready to become a
52
+ specification. A specification is only generated when every blocking
53
+ question has an explicit answer and every proposed assumption has been
54
+ explicitly accepted. Discovery is persisted, so an incomplete request
55
+ can be resumed across sessions and agent harnesses.
56
+
57
+ ## The problem it solves
58
+
59
+ AI agents can produce useful specifications, but the result is often a
60
+ throwaway chat response:
61
+
62
+ - it is not tied to the real codebase;
63
+ - it does not follow the project's own engineering rules;
64
+ - there is no record of who approved it or which exact version was
65
+ approved;
66
+ - switching agents loses context and history.
67
+
68
+ DevFlow keeps the specification, the evidence used to write it, the
69
+ constitution and the approval record inside the project. Approvals are
70
+ bound to SHA-256 digests, and the workflow state can be rebuilt from an
71
+ append-only event log.
72
+
73
+ ## Two specification contexts
74
+
75
+ DevFlow does not assume that a project already exists. The difference
76
+ between the two modes is where the context comes from, not a permanent
77
+ identity for the project:
78
+
79
+ | Context | Source of context | Typical use |
80
+ | --- | --- | --- |
81
+ | `existing` (default) | Analysed code, dependencies, conventions and the constitution, plus the declared architecture manifest when present | A change, fix, refactor or integration in a real codebase |
82
+ | `greenfield` | Requested requirements, a declared architecture manifest, stack, constraints and the constitution | The initial specification for a system that does not exist yet |
83
+
84
+ - `existing` is the default and preserves the historical behaviour.
85
+ - `greenfield` never invents existing code. It does not scaffold a
86
+ project, generate application code or implement tasks.
87
+ - Greenfield is a context for a specification execution, not a permanent
88
+ project identity. After implementation exists, switch back to
89
+ `existing`; the architecture manifest is kept and used as a
90
+ constraint.
91
+ - DevFlow never switches modes silently. Use `--project-mode` explicitly
92
+ when a run differs from the configured default.
93
+
94
+ ## Requirements
95
+
96
+ - Python 3.11 or newer.
97
+ - A POSIX operating system (Linux or macOS). Windows is not tested and is
98
+ not supported in this release, because the workflow locks require
99
+ `fcntl`.
100
+ - For agent-generated specifications: OpenCode installed and
101
+ authenticated on `PATH`. OpenCode is the only harness verified
102
+ end-to-end for this release.
103
+ - Git is not required. DevFlow does not initialize a repository, commit
104
+ files or run destructive commands.
105
+
106
+ ## Installation
107
+
108
+ ```bash
109
+ python -m venv .venv
110
+ source .venv/bin/activate
111
+ pip install devflow-toolkit
112
+ ```
113
+
114
+ To install a specific built artifact instead:
115
+
116
+ ```bash
117
+ pip install devflow_toolkit-0.3.0-py3-none-any.whl
118
+ ```
119
+
120
+ Verify the installation:
121
+
122
+ ```bash
123
+ devflow --help
124
+ devflow version
125
+ ```
126
+
127
+ ## Initialization
128
+
129
+ Run `devflow init` inside the project you want to manage:
130
+
131
+ ```bash
132
+ cd my-project
133
+ devflow init
134
+ ```
135
+
136
+ DevFlow inspects the existing project, detects its stack and profiles,
137
+ copies the applicable constitution documents, writes
138
+ `.devflow/config.yaml` and generates the integration for the selected
139
+ harness.
140
+
141
+ Common options:
142
+
143
+ ```bash
144
+ devflow init --harness opencode --mode non-interactive
145
+ devflow init --profile django-backend --name my-service
146
+ devflow init --project-mode greenfield
147
+ devflow init --no-agent
148
+ devflow init --yes
149
+ ```
150
+
151
+ `init --project-mode greenfield` creates `.devflow/architecture.yaml`
152
+ from a template when it does not exist. It never overwrites an existing
153
+ manifest. Edit the manifest before running a Greenfield specification;
154
+ until then, `spec` fails with a clear structural error.
155
+
156
+ `init` never overwrites an existing constitution document, configuration
157
+ file, specification, approval or unmanaged integration file. Running it
158
+ again refreshes missing constitution files and managed integration files
159
+ without destroying project work.
160
+
161
+ If an explicitly selected harness is not installed, `init` still records
162
+ the selection but prints a warning. Subsequent `spec` runs fall back to
163
+ deterministic static analysis until the executable is available.
164
+
165
+ ## Configuration
166
+
167
+ `.devflow/config.yaml` stores project settings. It references the
168
+ constitution documents; it does not duplicate their contents.
169
+
170
+ ```yaml
171
+ project:
172
+ name: my-service
173
+ type: backend
174
+ mode: existing
175
+ profiles:
176
+ - django-backend
177
+ constitution:
178
+ base: true
179
+ profile_specific: true
180
+ path: .devflow/constitution
181
+ files:
182
+ - constitution.md
183
+ - code-standards.md
184
+ - architecture.md
185
+ - django-standards.md
186
+ specifications:
187
+ path: .devflow/specs
188
+ plans:
189
+ path: .devflow/plans
190
+ templates:
191
+ path: .devflow/templates
192
+ agent:
193
+ harness: opencode
194
+ execution:
195
+ mode: non-interactive
196
+ permissions:
197
+ allow_project_read: true
198
+ allow_workflow_write: true
199
+ allow_source_code_changes: false
200
+ ```
201
+
202
+ `constitution.files` accepts plain file names inside the constitution
203
+ directory. Absolute paths, `..` and nested paths are rejected.
204
+
205
+ Existing configurations without `project.mode` load as `existing`.
206
+
207
+ ## Declared architecture
208
+
209
+ The declared architecture lives in `.devflow/architecture.yaml`, not in
210
+ `config.yaml`. It is a reviewable, versionable design decision. Example:
211
+
212
+ ```yaml
213
+ version: 1
214
+ style: clean-architecture
215
+ summary: >
216
+ REST API for contact management with domain separation.
217
+ modules:
218
+ - name: contacts
219
+ responsibility: Contact registration and queries
220
+ depends_on: [shared]
221
+ - name: shared
222
+ responsibility: Cross-cutting utilities
223
+ depends_on: []
224
+ layers:
225
+ - name: domain
226
+ may_depend_on: []
227
+ - name: application
228
+ may_depend_on: [domain]
229
+ - name: infrastructure
230
+ may_depend_on: [domain, application]
231
+ - name: presentation
232
+ may_depend_on: [application]
233
+ stack:
234
+ language: python
235
+ framework: django-rest-framework
236
+ database: postgresql
237
+ constraints:
238
+ containerization: docker
239
+ authentication: jwt
240
+ testing: pytest
241
+ quality_attributes:
242
+ - testability
243
+ - modularity
244
+ fitness_functions:
245
+ - domain must not import infrastructure
246
+ ```
247
+
248
+ `style` is free text. Clean Architecture, Hexagonal Architecture,
249
+ Microservices, Modular Monolith and Event-Driven are examples and
250
+ presets, not a closed list. Custom architectures are valid as long as
251
+ they are described in the manifest.
252
+
253
+ DevFlow validates structure and internal consistency only:
254
+
255
+ - required fields and non-empty values;
256
+ - duplicate module or layer names;
257
+ - references to unknown modules or layers;
258
+ - dependency cycles, reported as warnings;
259
+ - invalid YAML, unsafe paths, symlinks and oversized manifests.
260
+
261
+ It does **not** certify architectural quality. Contradictions and open
262
+ decisions must be recorded as specification questions.
263
+
264
+ `init` may create the template. `spec` only reads the manifest and never
265
+ modifies it. The manifest digest is recorded in `context.md` and in
266
+ `spec.md`, including an appendix with the declared manifest, so each
267
+ approval identifies the architecture version used. Greenfield
268
+ specifications require the manifest; existing-mode specifications use it
269
+ as an architectural constraint when it is present.
270
+
271
+ ### Harnesses
272
+
273
+ | Harness | Status in 0.3.0 |
274
+ | --- | --- |
275
+ | OpenCode | Verified end-to-end in non-interactive mode |
276
+ | Codex | Integration files are generated, but not verified for this release |
277
+ | Claude Code | Integration files are generated, but not verified for this release |
278
+ | Kiro | Integration files are generated, but not verified for this release |
279
+ | `none` | Deterministic static analysis only; no agent is invoked |
280
+
281
+ Do not treat an unverified adapter as a compatibility guarantee. The
282
+ generated files and command lines for Codex, Claude Code and Kiro may
283
+ change as those integrations are tested.
284
+
285
+ For OpenCode, DevFlow generates `AGENTS.md`, `opencode.json` and the
286
+ agents under `.opencode/agents/`. The project-level `opencode.json` can
287
+ also select the model used by the agent, for example:
288
+
289
+ ```json
290
+ {
291
+ "$schema": "https://opencode.ai/config.json",
292
+ "model": "provider/model-name"
293
+ }
294
+ ```
295
+
296
+ DevFlow creates `opencode.json` only when it does not exist and never
297
+ replaces an existing OpenCode configuration.
298
+
299
+ ### Permissions
300
+
301
+ `allow_workflow_write` controls writes to DevFlow artifacts.
302
+ `allow_spec_write` is accepted as a compatibility alias.
303
+ `allow_source_code_changes` is disabled by default.
304
+
305
+ DevFlow translates these settings into technical controls where the
306
+ harness exposes them. For OpenCode, the generated agents deny `edit`
307
+ outside `.devflow/specs/`, deny shell execution unless source changes are
308
+ explicitly allowed, and disable web access and subagents. Prompt text is
309
+ not treated as the only permission boundary.
310
+
311
+ When a harness cannot enforce a restriction technically, DevFlow prints
312
+ a warning instead of claiming that the restriction is guaranteed.
313
+
314
+ ## Discovery
315
+
316
+ Discovery is separate from specification. The project context decides
317
+ where evidence comes from; Discovery decides whether the request is
318
+ ready to become a specification.
319
+
320
+ Every new `devflow spec` request creates a persistent record at
321
+ `.devflow/specs/<id>-<slug>/discovery.yaml`. It is plain YAML and can be
322
+ reviewed, edited and committed:
323
+
324
+ ```yaml
325
+ version: 1
326
+ spec_id: "001"
327
+ change: "001-add-a-contact-form"
328
+ request: "Add a contact form"
329
+ project_mode: existing
330
+ status: awaiting_clarification
331
+ created_at: "2026-11-02T10:00:00Z"
332
+ updated_at: "2026-11-02T10:00:00Z"
333
+ questions:
334
+ - id: Q1
335
+ category: functional_scope
336
+ question: What should happen when the contact form is submitted?
337
+ reason: Persistence, confirmation and email delivery change scope.
338
+ blocking: true
339
+ status: pending
340
+ options: []
341
+ answer: null
342
+ answered_by: null
343
+ answered_at: null
344
+ assumptions:
345
+ - id: A1
346
+ question_id: Q1
347
+ value: Use `/contacto/` as the URL path.
348
+ reason: Internal routing must be visible before approval.
349
+ source: agent_default
350
+ status: pending_acceptance
351
+ accepted_by: null
352
+ accepted_at: null
353
+ ```
354
+
355
+ Each question has a `category` and an explicit `blocking` flag. The
356
+ blocking categories are scope, user-visible behaviour, data and
357
+ persistence, security and authentication, external integrations,
358
+ architecture boundaries, new dependencies and deployment. A question
359
+ may remain pending when it is genuinely non-blocking; it does not
360
+ prevent specification generation.
361
+
362
+ An assumption proposed by DevFlow uses `source: agent_default` and
363
+ starts as `pending_acceptance`. It never becomes accepted automatically.
364
+ A human must set `status: accepted` with `accepted_by` and `accepted_at`,
365
+ or reject it and record a different decision.
366
+
367
+ While blocking decisions remain:
368
+
369
+ - `discovery.yaml` and `context.md` are written;
370
+ - no `spec.md` is generated;
371
+ - `devflow approve --stage spec` refuses the change;
372
+ - the workflow status is `awaiting_clarification`.
373
+
374
+ Answer the questions in the file, or run an interactive harness, then
375
+ resume:
376
+
377
+ ```bash
378
+ devflow spec --continue 006
379
+ ```
380
+
381
+ `--continue` never regenerates or overwrites an approved specification.
382
+ It reuses a current, valid specification when its Discovery digest still
383
+ matches. If an answer changes before approval, DevFlow marks the old
384
+ specification stale, preserves it under `history/`, and generates a new
385
+ specification bound to the new Discovery digest.
386
+
387
+ The deterministic `--no-agent` path follows the same rules. It generates
388
+ Discovery, records it, and stops when a blocking decision remains. It
389
+ never invents an answer to continue.
390
+
391
+ Changes created with `0.2.0` that have no `discovery.yaml` remain
392
+ approvable as legacy changes, with an explicit warning. New changes
393
+ require Discovery.
394
+
395
+ ## Workflow
396
+
397
+ 1. Initialize the project with `devflow init`.
398
+ 2. Create a change and run Discovery.
399
+ 3. Answer blocking questions and accept or reject assumptions.
400
+ 4. Generate the specification with `devflow spec --continue <id>`.
401
+ 5. Review `spec.md` and resolve any remaining non-blocking questions.
402
+ 6. Record the approval.
403
+ 7. Inspect the state, artifacts and approval digests.
404
+
405
+ Available commands in `0.3.0`:
406
+
407
+ | Command | Status |
408
+ | --- | --- |
409
+ | `devflow init` | Implemented |
410
+ | `devflow spec` | Implemented: Discovery, specification, and `--continue` |
411
+ | `devflow approve <id> --stage spec` | Implemented |
412
+ | `devflow status <id>` | Implemented |
413
+ | `devflow version` | Implemented |
414
+ | `devflow plan` | Not implemented |
415
+ | `devflow approve <id> --stage plan` | Rejected |
416
+ | `devflow implement` | Not implemented |
417
+ | `devflow review` | Not implemented |
418
+ | `devflow approve <id> --stage review` | Rejected |
419
+
420
+ There is no separate `execute` command. `approve` is a human
421
+ authorization and never changes code. When the `implement` stage is
422
+ added, it will be the technical execution command, and it will remain
423
+ separate from approval.
424
+
425
+ ### Start, resume and generate a specification
426
+
427
+ Start a new change:
428
+
429
+ ```bash
430
+ devflow spec "Add a GET /patients endpoint that returns JSON"
431
+ ```
432
+
433
+ The command:
434
+
435
+ 1. loads and validates the configuration;
436
+ 2. loads the configured profiles and constitution;
437
+ 3. builds the context for the effective project mode (`existing` by
438
+ default, or `greenfield`);
439
+ 4. creates a persistent `discovery.yaml` with classified questions and
440
+ proposed assumptions;
441
+ 5. writes the deterministic evidence or declared architecture to
442
+ `context.md`;
443
+ 6. stops without `spec.md` when a blocking decision remains;
444
+ 7. if Discovery is complete, invokes the selected harness with the
445
+ shared DevFlow prompt, validates the returned specification, and
446
+ binds it to the Discovery digest;
447
+ 8. writes `spec.md` and registers the Discovery and specification
448
+ digests in the event log and the workflow projection.
449
+
450
+ Resume an existing change:
451
+
452
+ ```bash
453
+ devflow spec --continue 006
454
+ ```
455
+
456
+ `--continue` is not a new specification. It reuses the stored request
457
+ and project mode, loads Discovery, and stops until blocking decisions
458
+ are resolved. It reuses a current validated specification when the
459
+ Discovery digest still matches; otherwise it archives the old
460
+ specification and generates a new one.
461
+
462
+ For an existing project, DevFlow inspects relevant code and
463
+ dependencies. For Greenfield, it uses the declared architecture and
464
+ does not search for code or invent code references.
465
+
466
+ Useful options:
467
+
468
+ ```bash
469
+ devflow spec "Description" --harness opencode --mode non-interactive
470
+ devflow spec "Description" --no-agent
471
+ devflow spec "Change in a real project" --project-mode existing
472
+ devflow spec "Create a new service" --project-mode greenfield
473
+ devflow spec --continue 006
474
+ ```
475
+
476
+ If the harness is unavailable, fails, or returns an invalid document,
477
+ DevFlow writes a deterministic draft and reports the reason. The command
478
+ remains usable in CI and on machines without an AI harness, but the draft
479
+ still requires human review. A request that is not ready never receives
480
+ a silent deterministic specification: Discovery stops instead.
481
+
482
+ ### Check status
483
+
484
+ ```bash
485
+ devflow status 001
486
+ devflow status 001-add-a-get-patients-endpoint
487
+ ```
488
+
489
+ `status` shows the workflow state, registered artifacts and digests,
490
+ approvals, stale artifacts and orphan files. It reconciles
491
+ `workflow.yaml` from `events.jsonl` before reporting.
492
+
493
+ ### Approve the specification
494
+
495
+ ```bash
496
+ devflow approve 001 --stage spec
497
+ ```
498
+
499
+ Approval is explicit and binds the decision to the current artifact
500
+ digests. For a `0.3.0` change it binds `spec.md`, `discovery.yaml` and,
501
+ when a manifest applies, the architecture manifest digest. Repeating the
502
+ same approval is a no-op. If an artifact changes after validation,
503
+ DevFlow marks it stale and refuses approval until it is regenerated and
504
+ validated again.
505
+
506
+ Discovery must be complete before approval. If it is not, approval fails
507
+ and names the pending questions and assumptions. Legacy `0.2.0` changes
508
+ without `discovery.yaml` remain approvable with a warning.
509
+
510
+ Only the `spec` stage is available in `0.3.0`. `--stage plan` and
511
+ `--stage review` are rejected. There are no `plan`, `implement` or
512
+ `review` commands in this release.
513
+
514
+ ## Generated files
515
+
516
+ ```text
517
+ my-project/
518
+ ├── .devflow/
519
+ │ ├── config.yaml
520
+ │ ├── architecture.yaml # declared architecture (Greenfield)
521
+ │ ├── .specs.lock # serializes specification id assignment
522
+ │ ├── constitution/
523
+ │ │ ├── constitution.md
524
+ │ │ ├── code-standards.md
525
+ │ │ ├── architecture.md
526
+ │ │ └── django-standards.md # only when the profile is enabled
527
+ │ └── specs/
528
+ │ └── 001-add-patients-endpoint/
529
+ │ ├── discovery.yaml # persistent questions and answers
530
+ │ ├── context.md
531
+ │ ├── spec.md # only when Discovery is complete
532
+ │ ├── workflow.yaml # projection of events.jsonl
533
+ │ ├── events.jsonl # append-only source of truth
534
+ │ └── .lock # per-change advisory lock
535
+ ├── AGENTS.md
536
+ ├── opencode.json # when OpenCode is selected
537
+ └── .opencode/agents/ # when OpenCode is selected
538
+ ```
539
+
540
+ All managed files are identifiable: Markdown files contain
541
+ `<!-- devflow:managed -->`, and JSON files contain `"devflowManaged":
542
+ true`. Unmanaged files with the same names are left untouched and
543
+ reported.
544
+
545
+ ## How approvals and history work
546
+
547
+ `events.jsonl` is the source of truth. `workflow.yaml` is only a
548
+ projection: if it is deleted, lags behind or disagrees with the event log,
549
+ DevFlow rebuilds or rejects it rather than trusting it.
550
+
551
+ ```text
552
+ generated -> validated -> approved
553
+ | |
554
+ +-> rejected +-> stale
555
+ ```
556
+
557
+ - An approval stores the artifact kind and its SHA-256 digest.
558
+ - Editing an approved artifact makes it stale.
559
+ - A stale, unvalidated or orphan artifact cannot be approved.
560
+ - Semantic validation rejects malformed or inconsistent histories.
561
+ - Artifact and state writes are atomic; a failed write does not leave a
562
+ partially written managed file.
563
+ - Writes are restricted to the project and the configured directories.
564
+ Symlinks that escape the project are rejected or ignored.
565
+ - Specification directory allocation is serialized with a lock, so two
566
+ concurrent runs do not receive the same numeric id.
567
+
568
+ The event log is local and append-only, not cryptographically signed. A
569
+ user with full filesystem access can modify it; DevFlow detects
570
+ structural and semantic inconsistency, not deliberate tampering by an
571
+ administrator.
572
+
573
+ ## Updating DevFlow
574
+
575
+ ```bash
576
+ pip install --upgrade devflow-toolkit
577
+ devflow version
578
+ ```
579
+
580
+ Then run `devflow init` again in each project. The update:
581
+
582
+ - restores missing constitution documents;
583
+ - refreshes managed integration files;
584
+ - preserves existing constitution documents, specifications,
585
+ approvals and event logs.
586
+
587
+ Review `.devflow/config.yaml` after a major upgrade, because new options
588
+ may have been added. DevFlow does not silently rewrite user-modified
589
+ configuration.
590
+
591
+ ## Known limitations
592
+
593
+ - Only the specification stage is implemented. Planning,
594
+ implementation and review are not available.
595
+ - Greenfield mode produces a specification from a declared
596
+ architecture. It does not scaffold a project, generate application
597
+ code, create Docker or cloud infrastructure, or implement tasks.
598
+ - DevFlow validates the structure of the architecture manifest. It does
599
+ not certify that the architecture is correct, complete or appropriate.
600
+ - Only OpenCode has been verified end-to-end. Codex, Claude Code and
601
+ Kiro adapters are unverified scaffolds for future releases.
602
+ - Interactive harness mode exists, but the verified release path is
603
+ OpenCode non-interactive mode. Interactive mode requires a terminal.
604
+ - Without an available harness, output is produced by deterministic
605
+ static analysis. It is a starting draft, not a substitute for human
606
+ review.
607
+ - Static analysis is heuristic: it finds likely affected files, not a
608
+ complete impact map.
609
+ - DevFlow is POSIX-only in this release.
610
+ - The package does not provide a hosted service, telemetry or remote
611
+ synchronization. All state stays in the project.
612
+
613
+ ## Development
614
+
615
+ ```bash
616
+ python -m venv .venv
617
+ source .venv/bin/activate
618
+ pip install -e ".[dev]"
619
+ pytest
620
+ ruff check
621
+ python -m build
622
+ python -m twine check dist/*
623
+ ```
624
+
625
+ The test suite covers the core, CLI, state replay and harness adapters.
626
+ Release verification additionally installs the built wheel and sdist in
627
+ clean virtual environments and runs the consumer workflow from outside
628
+ the repository.
@@ -0,0 +1,63 @@
1
+ devflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ devflow/cli.py,sha256=ltV3J_ApTO0jYxQsuRAhxFzKVOBR8N-sMv2BUUbklI4,965
3
+ devflow/adapters/__init__.py,sha256=WcsjXQTKzHNzMAHx82-sdJQeR3ceHRVqLWTUtRlaraE,867
4
+ devflow/adapters/agents.py,sha256=4d54hDfBgnIP4zOKcZqAG-Qa-jfuuxzFL-akZS2qYtw,1309
5
+ devflow/adapters/base.py,sha256=YggY_IwHExdybl5S9NjwZSlmmcw9Y6z7DhQsl3JLvXs,2055
6
+ devflow/adapters/claude_code.py,sha256=7eM1Wc8L5rALBdcJin5aVn3M5vynj6yRXzsJdISwpxA,3140
7
+ devflow/adapters/codex.py,sha256=Zq2O805HiljC-zTQYhm76sIK63DamTiwRUyOt8S2Sk8,3026
8
+ devflow/adapters/detector.py,sha256=92BkNAvWs2Vh8H6xJzMweBDCw6yuYVg7sV4LoSZ8KFo,3291
9
+ devflow/adapters/instructions.py,sha256=LanvRhv-ZLtt_sjmE2tcX0br-aEn7GDisdUEG4YIsnE,7379
10
+ devflow/adapters/kiro.py,sha256=8l5y7ZYffg_T9eciM28NKGHil_zgdT96mAdYK4oBZ0U,6111
11
+ devflow/adapters/opencode.py,sha256=DonmvAKyWK2v5-X2XrL0n2iptFp7qLgOlh-X8n_8I-w,6492
12
+ devflow/adapters/registry.py,sha256=NLd_tf7dAiZUa6gbQFcwPogurZyjbMNbzjjXozAD4xs,1177
13
+ devflow/commands/__init__.py,sha256=yOLtd_4R4xdlMgAzihzIT35oyV_qcz0br-aoLebRj1c,157
14
+ devflow/commands/approve.py,sha256=oknp1Gd05I8sNqqU4W6q1BDdUk9feuxcHlxltoGZDJM,2740
15
+ devflow/commands/harness.py,sha256=r_RSAi7gXK8QNucC6eV-RzXHJycmmR03dzihqLVgdiU,2791
16
+ devflow/commands/init.py,sha256=Tv-YZeR8jGcHeIG9cHA5dFQDkpsyFC5Iw7nHMsRDvQQ,14416
17
+ devflow/commands/spec.py,sha256=JJzYFFNUYy1U3oC_LS6lfBnmD6yZBq7RR2Yj4_n7KcM,13960
18
+ devflow/commands/status.py,sha256=HtBCIF8U0bmkyS6wS7IEvggo89FzGRGBCsFfPrKzLpU,4369
19
+ devflow/core/__init__.py,sha256=hN7i4-PDaZ7y4P8qRpZl_lJvIiPyQaN1TDGnw2BecYU,427
20
+ devflow/core/architecture.py,sha256=qllllsUVqA76LiSU6z_s4U8dxMcs6ClKXU16HxI3yOI,13692
21
+ devflow/core/clock.py,sha256=KZROv6o51Ln1EzK00ySCxfc7WPZqPlaQhFfjfdc_TMY,1651
22
+ devflow/core/config.py,sha256=yypUaKXaAM0sqRdLKKtuJ1hHZtRQYzgzBNELsOJQpVA,20075
23
+ devflow/core/constitution.py,sha256=nPHyy7BuIyyqkn4y85UyWn2E7f5AWHbg4iZ0frF9SfE,4581
24
+ devflow/core/discovery.py,sha256=qqFmVdrRF9tViQtuvZPK2JHF5C9ddpZT1Lu3YsasCro,34246
25
+ devflow/core/ports.py,sha256=R6ybjAdJEdtTKFc4FMFTX0TVwRfDwPoWCsu-BHrhI5A,4071
26
+ devflow/core/profile_manager.py,sha256=QnnJka2KIKD2tCSWJkGTOUEFMgmQT0Z9Qv173JKWKHw,8937
27
+ devflow/core/project.py,sha256=SINU6KSRIpX5rPlPy8nWMfQuHas_VF1bAIVafhbcgCg,13330
28
+ devflow/core/spec_workflow.py,sha256=TEGVzMTNScTfZjV0ttfCtXkuUqOc4u29dCCrbw-cUlc,28447
29
+ devflow/core/specification.py,sha256=aHAL_U8Tl0YBokUJKneqUyCPenY6xtcPlZUgKmUsEMw,65719
30
+ devflow/core/artifacts/__init__.py,sha256=gt9xahPynoxv75FMq1ZJx91ILTIv4ExuvX1Ymrxwr2c,627
31
+ devflow/core/artifacts/errors.py,sha256=hwZxnLFcUTtEjDWtN6rUCkM69EN19LGVlc6HD-pNZyk,493
32
+ devflow/core/artifacts/models.py,sha256=xJjmY8jUAHxqYN9u1JEu8CbJB-IJg1xb9P-LDaP5_Hw,2049
33
+ devflow/core/artifacts/store.py,sha256=ZHAhWAFiqtviwhpfQ0GDkizndpcqtpU0opTbsSJKrWA,4167
34
+ devflow/core/state/__init__.py,sha256=PiHKck1ZzUTSNvZBrFnk1O20godD2-Ah1hsEku1OR78,1545
35
+ devflow/core/state/errors.py,sha256=dgF-x4TCxQTXc1OifyT8UZSU-0PBhATjO1x6OTMagac,1017
36
+ devflow/core/state/events.py,sha256=IfwFCC0jbrQsH1tzADyqwm8HtWo5fR7QDD85M6JH8N0,20698
37
+ devflow/core/state/locator.py,sha256=J6ZnVzcY_KzwKqBXbAOnfG9FrRzSCaYMqFeMQ7ptjIc,3256
38
+ devflow/core/state/lock.py,sha256=94llvwHtCc5WOw-Uq8kDCu4iOBpRM4ccp6Q6fLZpYZ0,2089
39
+ devflow/core/state/manager.py,sha256=eCCylS-qcECTGOBJi_qS54nv86u-bYKMcNauHDz7sFk,27850
40
+ devflow/core/state/models.py,sha256=4GTrS34ymbJIyBeZkcCi0z0e1bsq67vdxRSnSQ9O3gc,4654
41
+ devflow/core/state/transitions.py,sha256=Go0zLhxcujWhaZEGg7JMqcC_UJU_nEFEBbpKIqrCtrs,3581
42
+ devflow/models/__init__.py,sha256=hXX3IDZbHgklmuzVVlpiRs5SSPnrkO5kN1-k2hIEk7E,156
43
+ devflow/models/profile.py,sha256=j8KifeDQSN-wvzDJe1GGQQN9Vw7S2oncj75NNHpwpZs,2001
44
+ devflow/models/project.py,sha256=2CAMY-mPEnkVryndNOzCURxknbZnnN2MYuEE-RIUcp0,1303
45
+ devflow/profiles/ai-rag/profile.yaml,sha256=ut4c8DBDQyI_Aoe1Gbvu46A3n-wBcGKcj84Zt_0Ghac,458
46
+ devflow/profiles/ai-rag/constitution/ai-rag-standards.md,sha256=sU-uM9iH50_xaF0vzqYNggIbvEnzYYCgaY7HdzOB6HY,1749
47
+ devflow/profiles/base/profile.yaml,sha256=_V3Y51Rl9J5PjXwBAleD1I6iiwVuDRu81bYILfsbpCE,249
48
+ devflow/profiles/base/constitution/architecture.md,sha256=gcuRWaV1uETI9_yF0w2egcFOU8KQzywDFPb8rHlek90,1712
49
+ devflow/profiles/base/constitution/code-standards.md,sha256=mTABWYkqHv8oDouxu-fZbzpFMEU1DZCniK7CzV5bPr4,2484
50
+ devflow/profiles/base/constitution/constitution.md,sha256=5-HcB2jRE_RVt1FeNKCtfQXpTxchI3-Zaq2dz5kstto,2706
51
+ devflow/profiles/django-backend/profile.yaml,sha256=SNj7a3yamdJx-P69GvIJmLkC2svOs6NheY8eA90lucg,358
52
+ devflow/profiles/django-backend/constitution/django-standards.md,sha256=0M-XmxOpEmgIadcaVdf6OVmll8Oec0jEjcJ4C8MfwhQ,2052
53
+ devflow/profiles/fastapi-backend/profile.yaml,sha256=5_b-zWSX0HV-tw_2ntRCSa4DyP3NUqYWmxOh55pXYmc,321
54
+ devflow/profiles/fastapi-backend/constitution/fastapi-standards.md,sha256=iFKib4i_9z4wBQ9thl-uftg5g-CHwvmFWzMtLgA7CBk,1949
55
+ devflow/prompts/__init__.py,sha256=gLMUlyhaiEgTQ_cHsi01c5EtUzXyUNEHz6pKbA0disw,6582
56
+ devflow/prompts/discovery.md,sha256=rwuCgD70yhFCw3MbygPr5jOxGof2_naKcKUVOlvmRRc,3716
57
+ devflow/prompts/spec.greenfield.md,sha256=sVuEb_Diqwwz_I1AGme29uvVfSzp8_8hfPC00gDkOMI,4678
58
+ devflow/prompts/spec.md,sha256=nyDcVVFrgC2Q5PiUc4yZbM_SUdRMiBvQW-GB6hfU-8Y,3346
59
+ devflow_toolkit-0.3.0.dist-info/METADATA,sha256=l74ZavMpl7CC3W4pSdVFv9gflYePsyVJEXBVQZenf7U,22306
60
+ devflow_toolkit-0.3.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
61
+ devflow_toolkit-0.3.0.dist-info/entry_points.txt,sha256=wPmqE1081vi8s3xf-Wfzfvpl-44IKgwx7OGoLEK3u7o,44
62
+ devflow_toolkit-0.3.0.dist-info/licenses/LICENSE,sha256=Wa04lstC8Goe4b9IYfEYWB2k7nokYBejZl6NdyAl8rA,1077
63
+ devflow_toolkit-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ devflow = devflow.cli:app