Skip to content
Merged

v3 #6

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ For an existing repo, generate durable project knowledge before asking an agent
productize init existing
```

This writes `.productize/project/` docs for inventory, context, conventions, architecture, and promoted decisions. The command is deterministic and does not call a model.
This refreshes five generated read models under `.productize/project/`: `context.md`, `conventions.md`, `architecture.md`, `decisions.md`, and `constraints.md`. The command is deterministic and does not call a model. Put human-authored project guidance in `.productize/project/manual.md`; refreshes never own that file.

### 4. Run the lifecycle

Expand Down Expand Up @@ -145,6 +145,27 @@ steps, and recommends the exact next command before mutating files or running ag

See [docs/reusable-agents.md](docs/reusable-agents.md).

### Project knowledge lifecycle

The five canonical documents under `.productize/project/` are generated, portable
read models. Productize owns files carrying its `productize:project-knowledge`
marker and leaves unmarked files untouched. Keep deliberate human-authored
additions in `manual.md` so refreshes never compete with edits.

- `productize init existing` creates or explicitly refreshes project knowledge.
- A successful `productize sync` reconciles workflow artifacts into
`~/.productize/db/global.db` and refreshes project knowledge from relevant
repository facts, ADRs, and durable shared workflow memory.
- `productize archive` moves an eligible workflow first, then refreshes knowledge
from both active and archived workflows so accepted, deprecated, or superseded
decisions survive archival.

Knowledge refresh is a derived-read-model step. A sync or archive can complete
while the refresh result is marked `degraded`; text output prints every skipped
file and warning, and JSON exposes the optional `project_knowledge` object with
`updated`, `unchanged`, `skipped`, `warnings`, `source_checksum`, and `degraded`.
Run `productize sync` again after resolving the warning to repair stale knowledge.

### ACP runtimes (execution backends)

`setup` installs *skills* into 40+ editors, but **execution** (`tasks run`, `reviews fix`, `exec`) goes through an ACP-capable runtime. Productize speaks the Agent Client Protocol to whichever you choose:
Expand Down Expand Up @@ -194,8 +215,8 @@ productize runs watch <run-id> # stream a running job
| `productize workspaces ...` | Manage daemon workspace registrations. |
| `productize daemon start \| status \| stop` | Manage the background daemon. |
| `productize migrate` | Convert legacy workflow artifacts to frontmatter. |
| `productize sync` | Reconcile workflow artifacts into the global DB. |
| `productize archive` | Move completed workflows to `_archived/`. |
| `productize sync` | Reconcile workflow artifacts into the global DB and refresh project knowledge. |
| `productize archive` | Move completed workflows to `_archived/` and refresh project knowledge. |
| `productize upgrade` | Update the CLI to the latest release. |

Run `productize <command> --help` for full flags, or see the [CLI reference](docs/cli-reference.md).
Expand Down Expand Up @@ -247,11 +268,12 @@ See [docs/configuration.md](docs/configuration.md) for every key.
.productize/ ~/.productize/
├── config.toml ├── config.toml
├── project/ ├── daemon/daemon.sock
│ ├── inventory.md ├── db/global.db
│ ├── context.md ├── catalog/skills.json
│ ├── conventions.md ├── runs/
│ ├── architecture.md ├── logs/
│ └── decisions.md └── agents/
│ ├── context.md ├── db/global.db
│ ├── conventions.md ├── catalog/skills.json
│ ├── architecture.md ├── runs/
│ ├── decisions.md ├── logs/
│ ├── constraints.md └── agents/
│ └── manual.md (optional)
├── tasks/<slug>/
│ ├── _prd.md
│ ├── _techspec.md
Expand Down
10 changes: 7 additions & 3 deletions agents/productize-operator/AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ Always inspect existing context before recommending a route:

1. Read `.productize/project/context.md` when it exists.
2. Read `.productize/project/conventions.md` when it exists.
3. Read `.productize/project/decisions.md` when it exists.
4. Inspect `.productize/tasks/` for active workflow artifacts.
5. Treat tactical skills as internal implementation details unless the user asks
3. Read `.productize/project/architecture.md` when it exists.
4. Read `.productize/project/decisions.md` when it exists.
5. Read `.productize/project/constraints.md` when it exists.
6. Read `.productize/project/manual.md` when it exists; it contains human-authored
additions outside the generated project knowledge read models.
7. Inspect `.productize/tasks/` for active workflow artifacts.
8. Treat tactical skills as internal implementation details unless the user asks
for a specific skill by name.

## Route Selection
Expand Down
28 changes: 22 additions & 6 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Adopt a mature repository into Productize project knowledge.
productize init existing [path] [flags]
```

The command deterministically scans repository facts and writes durable context
under `.productize/project/`. It does not invoke an AI model. Use it before
The command deterministically scans repository facts and creates or refreshes
durable context under `.productize/project/`. It does not invoke an AI model. Use it before
creating PRDs, TechSpecs, or tasks in an existing codebase.

| Flag | Default | Description |
Expand All @@ -20,13 +20,17 @@ creating PRDs, TechSpecs, or tasks in an existing codebase.
| `--force` | `false` | Overwrite existing unmarked project knowledge files |
| `--format` | `text` | Output format: `text` or `json` |

Generated files:
Generated or refreshed files:

- `.productize/project/inventory.md`
- `.productize/project/context.md`
- `.productize/project/conventions.md`
- `.productize/project/architecture.md`
- `.productize/project/decisions.md`
- `.productize/project/constraints.md`

These five files are generated read models owned only when they carry the
`productize:project-knowledge` marker. Keep human-authored additions in
`.productize/project/manual.md`, which refresh never overwrites.

## `productize setup`

Expand Down Expand Up @@ -92,7 +96,8 @@ productize migrate [flags]

## `productize sync`

Reconcile workflow artifacts into daemon state.
Reconcile workflow artifacts into daemon state, then refresh canonical project
knowledge from repository facts, ADRs, and durable shared workflow memory.

```bash
productize sync [flags]
Expand All @@ -105,6 +110,12 @@ productize sync [flags]
| `--tasks-dir` | | Restrict sync to one task workflow directory |
| `--format` | `text` | Output format: `text` or `json` |

Text output reports project knowledge as `current` or `degraded`, followed by
the source checksum and any updated, unchanged, skipped, or warning entries.
JSON includes the optional `project_knowledge` object with `updated`,
`unchanged`, `skipped`, `warnings`, `source_checksum`, and `degraded`. If refresh
is degraded, resolve its warnings and run `productize sync` again to retry.

## `productize daemon`

Manage the shared home-scoped daemon.
Expand Down Expand Up @@ -204,7 +215,8 @@ configured retention policy.

## `productize archive`

Move fully completed workflows into the archive root.
Move fully completed workflows into the archive root, then refresh canonical
project knowledge from both active and archived workflows.

```bash
productize archive [flags]
Expand All @@ -217,6 +229,10 @@ productize archive [flags]
| `--tasks-dir` | | Restrict archiving to one task workflow directory |
| `--format` | `text` | Output format: `text` or `json` |

Archiving can succeed while its derived project-knowledge refresh is degraded.
The command reports the same text and JSON project-knowledge fields as
`productize sync`; warnings are not silent, and the next sync is the repair path.

## `productize exec`

Execute one ad hoc prompt.
Expand Down
42 changes: 33 additions & 9 deletions docs/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,28 @@ This scans repository facts without invoking an AI model and writes:

```
.productize/project/
├── inventory.md
├── context.md
├── conventions.md
├── architecture.md
└── decisions.md
```

Future PRD, TechSpec, task-generation, and task-execution prompts read these
files when present. Re-run `productize init existing` when project structure,
commands, conventions, or Productize workflow memory changes. Use `--dry-run`
to preview and `--force` only when replacing hand-written project docs is
intentional.
├── decisions.md
├── constraints.md
└── manual.md # optional, human-authored additions
```

The first five files are canonical generated read models. Productize rewrites
only files carrying its `productize:project-knowledge` marker; put durable
human-authored additions in `manual.md`. Idea, PRD, TechSpec, task-generation,
and task-execution workflows read all five canonical files when present, plus
`manual.md` when present. PRD and idea authoring use technical knowledge only
to understand feasibility and constraints, not to leak implementation details
into business artifacts.

`productize init existing` explicitly refreshes these read models. A successful
`productize sync` also refreshes them after cataloging on-disk workflow artifacts,
and `productize archive` refreshes them after moving the workflow so durable ADRs
and shared memory survive archival. Use `--dry-run` to preview adoption output;
use `--force` only to migrate intentionally replaceable legacy files into
Productize ownership.

---

Expand Down Expand Up @@ -133,6 +143,20 @@ productize archive

Completed workflows move to `.productize/tasks/_archived/<timestamp>-<id>-<slug>`, keeping your active task list clean. Use `productize sync` first if you want the global DB reconciled with on-disk artifacts.

Archiving also refreshes project knowledge under `.productize/project/`, folding
durable ADR content and shared workflow memory from active and archived workflows
into `context.md`, `conventions.md`, `architecture.md`, `decisions.md`, and
`constraints.md`. Accepted, deprecated, and superseded ADRs remain visible;
proposed ADRs are not promoted. Later workflows read those documents as durable
context, so decisions made in one PRD carry forward into the next.

Project knowledge is a derived read model, so archive or sync can complete even
when its refresh is degraded. Text output reports the degraded status, every
protected/skipped file, and every warning. JSON returns the optional
`project_knowledge` result with `updated`, `unchanged`, `skipped`, `warnings`,
`source_checksum`, and `degraded`. Resolve the warning and run `productize sync`
again to retry and repair stale knowledge; refresh failures are never silent.

---

## Resuming & inspecting
Expand Down
12 changes: 11 additions & 1 deletion extensions/idea-forge/skills/idea-forge/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ You MUST create a task for each phase and complete them in order:
- Derive the slug from the feature idea provided by the user.
- Use `.productize/tasks/<slug>/` as the target directory.
- If `_idea.md` already exists in the target directory, read it and operate in update mode.
- Read every existing canonical project knowledge document before shaping the idea:
- `.productize/project/context.md`
- `.productize/project/conventions.md`
- `.productize/project/architecture.md`
- `.productize/project/decisions.md`
- `.productize/project/constraints.md`
- Read `.productize/project/manual.md` when present for human-authored additions that are intentionally kept outside the generated read models.
- Use architecture, decisions, and constraints to assess feasibility and product boundaries without copying implementation detail into the idea artifact.
- If the directory does not exist, create it.
- Create `.productize/tasks/<slug>/adrs/` directory if it does not exist.

Expand All @@ -62,6 +70,7 @@ You MUST create a task for each phase and complete them in order:
- Complete at least one full clarification round before proceeding to research.

3. Discover context through parallel research.
- Seed codebase exploration with all five canonical project knowledge documents listed in step 1, plus `manual.md` when present, and verify relevant facts against the current repository.
- Spawn one Agent tool call to explore the codebase for relevant patterns, existing features, and architecture.
- Spawn a second Agent tool call to perform 3-7 web searches for market data and competitive intelligence.
- Use any available web search tools. If none are available, note the limitation and proceed with codebase exploration only.
Expand Down Expand Up @@ -120,7 +129,8 @@ You MUST create a task for each phase and complete them in order:
- After the debate, create an ADR for the scope decision:
- Read `references/adr-template.md`.
- Determine the next ADR number by listing existing files in `.productize/tasks/<slug>/adrs/`.
- Fill the template: recommended scope as "Decision", alternatives as "Alternatives Considered", trade-offs as "Consequences". Set Status to "Accepted" and Date to today.
- Fill the template: recommended scope as "Decision", alternatives as "Alternatives Considered", trade-offs as "Consequences". Set `kind` to `scope`, `status` to `accepted`, `date` to today, and `supersedes` to a YAML list of ADR references replaced by this decision (for example, `ADR-001`) or `[]`. Keep the Markdown Status and Date sections aligned with that metadata.
- When `supersedes` is non-empty, update each replaced ADR's metadata status to `superseded` and its Markdown Status to `Superseded by ADR-NNN`, naming the new ADR.
- Write the ADR to `.productize/tasks/<slug>/adrs/adr-NNN.md` (zero-padded 3-digit number).

6. Scan for opportunities.
Expand Down
11 changes: 11 additions & 0 deletions extensions/idea-forge/skills/idea-forge/references/adr-template.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
kind: <architecture|product|scope|technical>
status: <proposed|accepted|deprecated|superseded>
date: YYYY-MM-DD
supersedes: []
---

# ADR-XXX: [Title]

## Status
Expand Down Expand Up @@ -46,6 +53,10 @@ YYYY-MM-DD

- [List risks and mitigation strategies]

## Constraints

- [List hard constraints established by this decision, or "None"]

## Implementation Notes

[Any specific implementation details, migration steps, or technical notes relevant to this decision.]
Expand Down
25 changes: 25 additions & 0 deletions internal/api/client/client_transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ func TestClientOperatorRequestsUseCanonicalContract(t *testing.T) {
return jsonStructResponse(t, http.StatusOK, contract.ArchiveResponse{
Archived: true,
ArchivedAt: &syncedAt,
ProjectKnowledge: &contract.ProjectKnowledgeRefreshResult{
Updated: []string{".productize/project/decisions.md"},
Unchanged: []string{},
Skipped: []string{},
Warnings: []string{"project knowledge refresh failed"},
SourceChecksum: "archive-checksum",
Degraded: true,
},
}), nil
case http.MethodPost + " /api/sync":
var payload contract.SyncRequest
Expand All @@ -385,6 +393,13 @@ func TestClientOperatorRequestsUseCanonicalContract(t *testing.T) {
SyncedAt: &syncedAt,
WorkflowsScanned: 3,
SyncedPaths: []string{"/tmp/workspace/.productize/tasks/demo"},
ProjectKnowledge: &contract.ProjectKnowledgeRefreshResult{
Updated: []string{},
Unchanged: []string{".productize/project/context.md"},
Skipped: []string{},
Warnings: []string{},
SourceChecksum: "sync-checksum",
},
}), nil
default:
t.Fatalf("unexpected request %s %s", req.Method, req.URL.RequestURI())
Expand Down Expand Up @@ -471,6 +486,11 @@ func TestClientOperatorRequestsUseCanonicalContract(t *testing.T) {
if !archiveResult.Archived || archiveResult.ArchivedAt == nil || !archiveResult.ArchivedAt.Equal(syncedAt) {
t.Fatalf("ArchiveTaskWorkflow() = %#v, want archived result", archiveResult)
}
if archiveResult.ProjectKnowledge == nil || !archiveResult.ProjectKnowledge.Degraded ||
archiveResult.ProjectKnowledge.SourceChecksum != "archive-checksum" ||
len(archiveResult.ProjectKnowledge.Updated) != 1 || len(archiveResult.ProjectKnowledge.Warnings) != 1 {
t.Fatalf("ArchiveTaskWorkflow().ProjectKnowledge = %#v, want lossless result", archiveResult.ProjectKnowledge)
}

syncResult, err := client.SyncWorkflow(context.Background(), apicore.SyncRequest{
Workspace: "/tmp/workspace",
Expand All @@ -482,6 +502,11 @@ func TestClientOperatorRequestsUseCanonicalContract(t *testing.T) {
if syncResult.WorkspaceID != workspace.ID || syncResult.WorkflowSlug != "demo" || syncResult.WorkflowsScanned != 3 {
t.Fatalf("SyncWorkflow() = %#v, want canonical sync result", syncResult)
}
if syncResult.ProjectKnowledge == nil || syncResult.ProjectKnowledge.Degraded ||
syncResult.ProjectKnowledge.SourceChecksum != "sync-checksum" ||
len(syncResult.ProjectKnowledge.Unchanged) != 1 {
t.Fatalf("SyncWorkflow().ProjectKnowledge = %#v, want lossless result", syncResult.ProjectKnowledge)
}

if _, err := client.GetWorkspace(
context.Background(),
Expand Down
Loading