agentforge-framework 0.2.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.
- agentforge_framework/.claude-plugin/plugin.json +4 -0
- agentforge_framework/__init__.py +3 -0
- agentforge_framework/agents/__init__.py +92 -0
- agentforge_framework/agents/architect.py +146 -0
- agentforge_framework/agents/implementer.py +162 -0
- agentforge_framework/agents/orchestrator.py +588 -0
- agentforge_framework/agents/reviewer.py +335 -0
- agentforge_framework/agents/security.py +138 -0
- agentforge_framework/agents/tester.py +125 -0
- agentforge_framework/cli.py +461 -0
- agentforge_framework/context/__init__.py +1 -0
- agentforge_framework/context/extractors/__init__.py +76 -0
- agentforge_framework/context/extractors/base.py +47 -0
- agentforge_framework/context/extractors/python.py +65 -0
- agentforge_framework/context/extractors/sql.py +121 -0
- agentforge_framework/context/extractors/yaml.py +59 -0
- agentforge_framework/context/prompt.py +104 -0
- agentforge_framework/context/resolver.py +185 -0
- agentforge_framework/core/__init__.py +1 -0
- agentforge_framework/core/commands.py +170 -0
- agentforge_framework/core/config.py +90 -0
- agentforge_framework/core/contracts.py +875 -0
- agentforge_framework/core/gates.py +333 -0
- agentforge_framework/core/issues.py +697 -0
- agentforge_framework/core/plan_format.py +272 -0
- agentforge_framework/core/process.py +141 -0
- agentforge_framework/core/project.py +262 -0
- agentforge_framework/core/registry.py +455 -0
- agentforge_framework/core/repo.py +185 -0
- agentforge_framework/core/router.py +1 -0
- agentforge_framework/core/runtime.py +639 -0
- agentforge_framework/core/skills.py +255 -0
- agentforge_framework/core/workflow.py +215 -0
- agentforge_framework/plugins/__init__.py +35 -0
- agentforge_framework/plugins/databricks/__init__.py +86 -0
- agentforge_framework/plugins/pyspark/__init__.py +57 -0
- agentforge_framework/plugins/python/__init__.py +45 -0
- agentforge_framework/plugins/sql/__init__.py +377 -0
- agentforge_framework/providers/__init__.py +48 -0
- agentforge_framework/providers/base.py +248 -0
- agentforge_framework/providers/claude.py +159 -0
- agentforge_framework/providers/codex.py +139 -0
- agentforge_framework/skills/MANIFEST.yaml +157 -0
- agentforge_framework/skills/NOTICE +49 -0
- agentforge_framework/skills/domain-modeling/ADR-FORMAT.md +47 -0
- agentforge_framework/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- agentforge_framework/skills/domain-modeling/SKILL.md +74 -0
- agentforge_framework/skills/domain-modeling/agents/openai.yaml +3 -0
- agentforge_framework/skills/grill-with-docs/SKILL.md +76 -0
- agentforge_framework/skills/grilling/SKILL.md +28 -0
- agentforge_framework/skills/grilling/agents/openai.yaml +3 -0
- agentforge_framework/skills/to-spec/SKILL.md +75 -0
- agentforge_framework/skills/to-spec/agents/openai.yaml +5 -0
- agentforge_framework/skills/to-tickets/SKILL.md +105 -0
- agentforge_framework/skills/to-tickets/agents/openai.yaml +5 -0
- agentforge_framework/skills/unslop/SKILL.md +131 -0
- agentforge_framework/skills/unslop/evals/fixtures/silhouette/human_reference.json +66 -0
- agentforge_framework/skills/unslop/scripts/_lang.py +106 -0
- agentforge_framework/skills/unslop/scripts/banned_phrase_scan.py +784 -0
- agentforge_framework/skills/unslop/scripts/calibrate_pairs.py +580 -0
- agentforge_framework/skills/unslop/scripts/calibrate_score.py +273 -0
- agentforge_framework/skills/unslop/scripts/check_packs.py +80 -0
- agentforge_framework/skills/unslop/scripts/check_suggestions.py +225 -0
- agentforge_framework/skills/unslop/scripts/contribute.py +373 -0
- agentforge_framework/skills/unslop/scripts/diff_check.py +139 -0
- agentforge_framework/skills/unslop/scripts/extract_constraints.py +201 -0
- agentforge_framework/skills/unslop/scripts/harvest_classify.py +223 -0
- agentforge_framework/skills/unslop/scripts/harvest_samples.py +534 -0
- agentforge_framework/skills/unslop/scripts/readability_metrics.py +295 -0
- agentforge_framework/skills/unslop/scripts/refresh_status.py +154 -0
- agentforge_framework/skills/unslop/scripts/silhouette_scan.py +390 -0
- agentforge_framework/skills/unslop/scripts/structure_scan.py +322 -0
- agentforge_framework/skills/unslop/scripts/suggest.py +211 -0
- agentforge_framework/skills/unslop/scripts/validate_preservation.py +409 -0
- agentforge_framework/skills/unslop/scripts/voice_card.py +496 -0
- agentforge_framework/skills/unslop/scripts/voice_profile.py +194 -0
- agentforge_framework/skills/unslop/scripts/voice_score.py +271 -0
- agentforge_framework/skills/unslop/scripts/wiki_sync.py +479 -0
- agentforge_framework/skills/write-plainly/SKILL.md +94 -0
- agentforge_framework/workflows/bugfix.yaml +8 -0
- agentforge_framework/workflows/feature.yaml +16 -0
- agentforge_framework/workflows/review.yaml +10 -0
- agentforge_framework-0.2.0.dist-info/METADATA +321 -0
- agentforge_framework-0.2.0.dist-info/RECORD +89 -0
- agentforge_framework-0.2.0.dist-info/WHEEL +5 -0
- agentforge_framework-0.2.0.dist-info/entry_points.txt +3 -0
- agentforge_framework-0.2.0.dist-info/licenses/LICENSE +202 -0
- agentforge_framework-0.2.0.dist-info/licenses/src/agentforge_framework/skills/NOTICE +49 -0
- agentforge_framework-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# The skill bundle. Mostly third-party content, tracked deliberately.
|
|
2
|
+
#
|
|
3
|
+
# Nothing in `agentforge_framework` imports this directory. Markdown is read as
|
|
4
|
+
# text; Python is invoked as a subprocess with `sys.executable` by absolute path.
|
|
5
|
+
# See docs/adr/0006 for why this is vendored rather than depended upon.
|
|
6
|
+
#
|
|
7
|
+
# To refresh a skill: re-copy from upstream at a new commit, update `commit`
|
|
8
|
+
# and `vendored_at`, and re-run the tests. Never edit vendored files in place —
|
|
9
|
+
# a local edit that upstream does not know about turns every future refresh
|
|
10
|
+
# into a manual merge.
|
|
11
|
+
#
|
|
12
|
+
# `first_party` at the bottom is the exception, and the reason it is listed here
|
|
13
|
+
# is so that a refresh never mistakes it for something to overwrite.
|
|
14
|
+
|
|
15
|
+
version: 1
|
|
16
|
+
|
|
17
|
+
upstreams:
|
|
18
|
+
mattpocock-skills:
|
|
19
|
+
repo: https://github.com/mattpocock/skills
|
|
20
|
+
commit: 5b15a47f2d7150f545fbcacbfe381787fc0230dc
|
|
21
|
+
license: MIT
|
|
22
|
+
license_source: LICENSE file in upstream repository
|
|
23
|
+
copyright: Copyright (c) 2026 Matt Pocock
|
|
24
|
+
vendored_at: 2026-08-24
|
|
25
|
+
|
|
26
|
+
unslop:
|
|
27
|
+
repo: https://github.com/theclaymethod/unslop
|
|
28
|
+
commit: d81f5196167ded24f46fced04958c0c12d681798
|
|
29
|
+
license: MIT
|
|
30
|
+
license_source: >-
|
|
31
|
+
README.md only ("Python 3.8+ and any supported coding agent. Licensed
|
|
32
|
+
MIT."). The repository has no LICENSE file and the GitHub licence API
|
|
33
|
+
reports null. The grant is unambiguous in prose but names no copyright
|
|
34
|
+
holder and includes no warranty disclaimer.
|
|
35
|
+
copyright: "Unstated upstream; attributed to the theclaymethod/unslop authors"
|
|
36
|
+
vendored_at: 2026-08-24
|
|
37
|
+
license_open_item:
|
|
38
|
+
asked: https://github.com/theclaymethod/unslop/issues/9
|
|
39
|
+
asked_at: 2026-08-25
|
|
40
|
+
answered: null
|
|
41
|
+
gates: >-
|
|
42
|
+
PyPI, and not the tag. A release is code somebody chose to visit; an
|
|
43
|
+
index entry is the same code reaching people who did not, and that is
|
|
44
|
+
where a grant recorded only in prose stops being ours to accept on a
|
|
45
|
+
stranger's behalf. Nothing moves until upstream answers: `copyright`
|
|
46
|
+
above stays our attribution rather than a reproduction of their notice,
|
|
47
|
+
and the NOTICE file alongside this one says so in the same terms.
|
|
48
|
+
|
|
49
|
+
skills:
|
|
50
|
+
grilling:
|
|
51
|
+
upstream: mattpocock-skills
|
|
52
|
+
consumer: orchestrator
|
|
53
|
+
stage: plan
|
|
54
|
+
purpose: Interview the human until the plan is shared understanding.
|
|
55
|
+
|
|
56
|
+
domain-modeling:
|
|
57
|
+
upstream: mattpocock-skills
|
|
58
|
+
consumer: orchestrator
|
|
59
|
+
stage: plan
|
|
60
|
+
purpose: >-
|
|
61
|
+
Maintain the target repository's CONTEXT.md glossary and ADRs as the
|
|
62
|
+
interview resolves terms and decisions.
|
|
63
|
+
|
|
64
|
+
to-spec:
|
|
65
|
+
upstream: mattpocock-skills
|
|
66
|
+
consumer: orchestrator
|
|
67
|
+
stage: plan
|
|
68
|
+
purpose: >-
|
|
69
|
+
Synthesise the interview into a spec without further questioning. It
|
|
70
|
+
also ends by publishing to an issue tracker and applying a
|
|
71
|
+
`ready-for-agent` label, which overlaps AgentForge's own issue handling.
|
|
72
|
+
Reconciled structurally rather than by prompt: `agentforge plan` runs
|
|
73
|
+
default-deny (ADR-0007), so the Orchestrator cannot reach `gh` and the
|
|
74
|
+
single-Issue guarantee holds however the skill is written.
|
|
75
|
+
|
|
76
|
+
to-tickets:
|
|
77
|
+
upstream: mattpocock-skills
|
|
78
|
+
consumer: orchestrator
|
|
79
|
+
stage: plan
|
|
80
|
+
purpose: Break the spec into the frozen plan and Roster that ADR-0003 requires.
|
|
81
|
+
|
|
82
|
+
unslop:
|
|
83
|
+
upstream: unslop
|
|
84
|
+
consumer: reviewer
|
|
85
|
+
stage: runtime
|
|
86
|
+
purpose: >-
|
|
87
|
+
Deterministic prose scanning, exposed as the `agentforge unslop` Command.
|
|
88
|
+
No inference involved.
|
|
89
|
+
entrypoints:
|
|
90
|
+
- scripts/banned_phrase_scan.py
|
|
91
|
+
- scripts/structure_scan.py
|
|
92
|
+
- scripts/silhouette_scan.py
|
|
93
|
+
vendored_partially: true
|
|
94
|
+
included:
|
|
95
|
+
- SKILL.md
|
|
96
|
+
- scripts/ # all 21 scripts; the three scanners import `_lang`
|
|
97
|
+
- evals/fixtures/silhouette/human_reference.json
|
|
98
|
+
excluded:
|
|
99
|
+
- references/ # 220K of skill doctrine; only needed for prompt fragments
|
|
100
|
+
- presets/ # voice presets; only needed for `teach` and `mimic`
|
|
101
|
+
- evals/ # except the one fixture above
|
|
102
|
+
- docs/, plans/, assets/
|
|
103
|
+
notes: >-
|
|
104
|
+
silhouette_scan.py resolves
|
|
105
|
+
`Path(__file__).parent.parent / "evals/fixtures/silhouette/human_reference.json"`,
|
|
106
|
+
so `scripts/` and `evals/` must stay siblings under `unslop/`. All three
|
|
107
|
+
scanners call `sys.path.insert(0, HERE)` themselves, so the sibling
|
|
108
|
+
`_lang` import resolves regardless of working directory. Excluding
|
|
109
|
+
`references/` is what makes the Command-only decision cheap; restoring
|
|
110
|
+
prompt fragments means vendoring it.
|
|
111
|
+
|
|
112
|
+
# Not vendored, deliberately: `implement` and `code-review` from
|
|
113
|
+
# mattpocock-skills. Those stages are what AgentForge's own Implementer and
|
|
114
|
+
# Reviewer Roles exist to do, and shipping both would mean maintaining two
|
|
115
|
+
# competing implementations of the same step.
|
|
116
|
+
|
|
117
|
+
# --- AgentForge's own ------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
first_party:
|
|
120
|
+
grill-with-docs:
|
|
121
|
+
consumer: orchestrator
|
|
122
|
+
stage: plan
|
|
123
|
+
composes: [grilling, domain-modeling]
|
|
124
|
+
purpose: >-
|
|
125
|
+
The interview and the writing-down as one job, plus the part neither
|
|
126
|
+
vendored skill knows: that the plan freezes when it is filed, so a
|
|
127
|
+
question not asked here becomes a guess made later by an Agent with less
|
|
128
|
+
context than the interviewer had.
|
|
129
|
+
why_not_vendored: >-
|
|
130
|
+
Upstream ships a skill of the same name at
|
|
131
|
+
skills/engineering/grill-with-docs, and its whole body is "Call the Skill
|
|
132
|
+
tool twice, for grilling and domain-modeling". That works on a Provider
|
|
133
|
+
with a Skill tool and does nothing on one without: delivered as a Fragment
|
|
134
|
+
it would reach the Agent as an instruction pointing at a mechanism that is
|
|
135
|
+
not there, and the interview method would silently never arrive
|
|
136
|
+
(ADR-0005). AgentForge ships its own composite instead, and
|
|
137
|
+
`core.skills.COMPOSED` expands it into its parts on the Fragment path.
|
|
138
|
+
Deliberately not vendored — do not add it on the next refresh.
|
|
139
|
+
|
|
140
|
+
write-plainly:
|
|
141
|
+
consumer: reviewer
|
|
142
|
+
stage: runtime
|
|
143
|
+
composes: []
|
|
144
|
+
purpose: >-
|
|
145
|
+
What the three `unslop` scanners count, written as guidance for the draft
|
|
146
|
+
rather than as findings on a draft. Delivered before the Reviewer's first
|
|
147
|
+
attempt; deliberately not delivered on a rewrite, where every finding
|
|
148
|
+
already names the phrase, the line, and a replacement.
|
|
149
|
+
why_not_vendored: >-
|
|
150
|
+
Upstream's own `unslop/SKILL.md` is a routing table for a human typing
|
|
151
|
+
`/unslop cleanup`, and its doctrine lives entirely in `references/`, which
|
|
152
|
+
this bundle excludes (`vendored_partially: true` above). Delivered as a
|
|
153
|
+
Fragment it would reach the Reviewer as a menu pointing at ten files
|
|
154
|
+
nobody ships. This file states only what the three vendored scanners
|
|
155
|
+
actually enforce, so it duplicates no upstream text and goes stale only
|
|
156
|
+
when the scanners change. Deliberately not vendored — do not add
|
|
157
|
+
upstream's SKILL.md body on the next refresh.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
AgentForge bundles third-party skills under src/agentforge_framework/skills/.
|
|
2
|
+
Machine-readable provenance, including commit SHAs and what was excluded from
|
|
3
|
+
each bundle, is in MANIFEST.yaml alongside this file.
|
|
4
|
+
|
|
5
|
+
================================================================================
|
|
6
|
+
mattpocock/skills — grilling, domain-modeling, to-spec, to-tickets
|
|
7
|
+
https://github.com/mattpocock/skills @ 5b15a47f2d7150f545fbcacbfe381787fc0230dc
|
|
8
|
+
================================================================================
|
|
9
|
+
|
|
10
|
+
MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Matt Pocock
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
|
|
32
|
+
================================================================================
|
|
33
|
+
theclaymethod/unslop — SKILL.md, scripts/, one silhouette fixture
|
|
34
|
+
https://github.com/theclaymethod/unslop @ d81f5196167ded24f46fced04958c0c12d681798
|
|
35
|
+
================================================================================
|
|
36
|
+
|
|
37
|
+
Licensed MIT by the theclaymethod/unslop authors.
|
|
38
|
+
|
|
39
|
+
The upstream repository states its licence in README.md ("Python 3.8+ and any
|
|
40
|
+
supported coding agent. Licensed MIT.") and carries no LICENSE file. The
|
|
41
|
+
GitHub licence API reports null for this repository. The grant itself is clear,
|
|
42
|
+
but no copyright holder is named upstream and no warranty disclaimer is
|
|
43
|
+
published, so neither can be reproduced here.
|
|
44
|
+
|
|
45
|
+
Open item: upstream has been asked to add a LICENSE file naming the copyright
|
|
46
|
+
holder, at https://github.com/theclaymethod/unslop/issues/9 (opened 2026-08-25,
|
|
47
|
+
unanswered as of 2026-08-27). Until it is answered this bundle carries a licence
|
|
48
|
+
grant recorded in prose rather than a canonical licence text, and the
|
|
49
|
+
attribution above is ours rather than a reproduction of theirs.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ADR Format
|
|
2
|
+
|
|
3
|
+
ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc.
|
|
4
|
+
|
|
5
|
+
Create the `docs/adr/` directory lazily: only when the first ADR is needed.
|
|
6
|
+
|
|
7
|
+
## Template
|
|
8
|
+
|
|
9
|
+
```md
|
|
10
|
+
# {Short title of the decision}
|
|
11
|
+
|
|
12
|
+
{1-3 sentences: what's the context, what did we decide, and why.}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why*, not in filling out sections.
|
|
16
|
+
|
|
17
|
+
## Optional sections
|
|
18
|
+
|
|
19
|
+
Only include these when they add genuine value. Most ADRs won't need them.
|
|
20
|
+
|
|
21
|
+
- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`): useful when decisions are revisited
|
|
22
|
+
- **Considered Options**: only when the rejected alternatives are worth remembering
|
|
23
|
+
- **Consequences**: only when non-obvious downstream effects need to be called out
|
|
24
|
+
|
|
25
|
+
## Numbering
|
|
26
|
+
|
|
27
|
+
Scan `docs/adr/` for the highest existing number and increment by one.
|
|
28
|
+
|
|
29
|
+
## When to offer an ADR
|
|
30
|
+
|
|
31
|
+
All three of these must be true:
|
|
32
|
+
|
|
33
|
+
1. **Hard to reverse**: the cost of changing your mind later is meaningful
|
|
34
|
+
2. **Surprising without context**: a future reader will look at the code and wonder "why on earth did they do it this way?"
|
|
35
|
+
3. **The result of a real trade-off**: there were genuine alternatives and you picked one for specific reasons
|
|
36
|
+
|
|
37
|
+
If a decision is easy to reverse, skip it: you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."
|
|
38
|
+
|
|
39
|
+
### What qualifies
|
|
40
|
+
|
|
41
|
+
- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
|
|
42
|
+
- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
|
|
43
|
+
- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library: just the ones that would take a quarter to swap out.
|
|
44
|
+
- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
|
|
45
|
+
- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
|
|
46
|
+
- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
|
|
47
|
+
- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it; otherwise someone will suggest GraphQL again in six months.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# CONTEXT.md Format
|
|
2
|
+
|
|
3
|
+
## Structure
|
|
4
|
+
|
|
5
|
+
```md
|
|
6
|
+
# {Context Name}
|
|
7
|
+
|
|
8
|
+
{One or two sentence description of what this context is and why it exists.}
|
|
9
|
+
|
|
10
|
+
## Language
|
|
11
|
+
|
|
12
|
+
**Order**:
|
|
13
|
+
{A one or two sentence description of the term}
|
|
14
|
+
_Avoid_: Purchase, transaction
|
|
15
|
+
|
|
16
|
+
**Invoice**:
|
|
17
|
+
A request for payment sent to a customer after delivery.
|
|
18
|
+
_Avoid_: Bill, payment request
|
|
19
|
+
|
|
20
|
+
**Customer**:
|
|
21
|
+
A person or organization that places orders.
|
|
22
|
+
_Avoid_: Client, buyer, account
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`.
|
|
28
|
+
- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does.
|
|
29
|
+
- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
|
|
30
|
+
- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
|
|
31
|
+
|
|
32
|
+
## Single vs multi-context repos
|
|
33
|
+
|
|
34
|
+
**Single context (most repos):** One `CONTEXT.md` at the repo root.
|
|
35
|
+
|
|
36
|
+
**Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other:
|
|
37
|
+
|
|
38
|
+
```md
|
|
39
|
+
# Context Map
|
|
40
|
+
|
|
41
|
+
## Contexts
|
|
42
|
+
|
|
43
|
+
- [Ordering](./src/ordering/CONTEXT.md): receives and tracks customer orders
|
|
44
|
+
- [Billing](./src/billing/CONTEXT.md): generates invoices and processes payments
|
|
45
|
+
- [Fulfillment](./src/fulfillment/CONTEXT.md): manages warehouse picking and shipping
|
|
46
|
+
|
|
47
|
+
## Relationships
|
|
48
|
+
|
|
49
|
+
- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
|
|
50
|
+
- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
|
|
51
|
+
- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The skill infers which structure applies:
|
|
55
|
+
|
|
56
|
+
- If `CONTEXT-MAP.md` exists, read it to find contexts
|
|
57
|
+
- If only a root `CONTEXT.md` exists, single context
|
|
58
|
+
- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved
|
|
59
|
+
|
|
60
|
+
When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: domain-modeling
|
|
3
|
+
description: Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a CONTEXT.md, or recording or editing an ADR.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Domain Modeling
|
|
7
|
+
|
|
8
|
+
Actively build and sharpen the project's domain model as you design. This is the *active* discipline: challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely *reading* `CONTEXT.md` for vocabulary is not this skill: that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.)
|
|
9
|
+
|
|
10
|
+
## File structure
|
|
11
|
+
|
|
12
|
+
Most repos have a single context:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
/
|
|
16
|
+
├── CONTEXT.md
|
|
17
|
+
├── docs/
|
|
18
|
+
│ └── adr/
|
|
19
|
+
│ ├── 0001-event-sourced-orders.md
|
|
20
|
+
│ └── 0002-postgres-for-write-model.md
|
|
21
|
+
└── src/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
/
|
|
28
|
+
├── CONTEXT-MAP.md
|
|
29
|
+
├── docs/
|
|
30
|
+
│ └── adr/ ← system-wide decisions
|
|
31
|
+
├── src/
|
|
32
|
+
│ ├── ordering/
|
|
33
|
+
│ │ ├── CONTEXT.md
|
|
34
|
+
│ │ └── docs/adr/ ← context-specific decisions
|
|
35
|
+
│ └── billing/
|
|
36
|
+
│ ├── CONTEXT.md
|
|
37
|
+
│ └── docs/adr/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Create files lazily: only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed.
|
|
41
|
+
|
|
42
|
+
## During the session
|
|
43
|
+
|
|
44
|
+
### Challenge against the glossary
|
|
45
|
+
|
|
46
|
+
When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y. Which is it?"
|
|
47
|
+
|
|
48
|
+
### Sharpen fuzzy language
|
|
49
|
+
|
|
50
|
+
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account': do you mean the Customer or the User? Those are different things."
|
|
51
|
+
|
|
52
|
+
### Discuss concrete scenarios
|
|
53
|
+
|
|
54
|
+
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
|
|
55
|
+
|
|
56
|
+
### Cross-reference with code
|
|
57
|
+
|
|
58
|
+
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible. Which is right?"
|
|
59
|
+
|
|
60
|
+
### Update CONTEXT.md inline
|
|
61
|
+
|
|
62
|
+
When a term is resolved, update `CONTEXT.md` right there. Don't batch these up: capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).
|
|
63
|
+
|
|
64
|
+
`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.
|
|
65
|
+
|
|
66
|
+
### Offer ADRs sparingly
|
|
67
|
+
|
|
68
|
+
Only offer to create an ADR when all three are true:
|
|
69
|
+
|
|
70
|
+
1. **Hard to reverse**: the cost of changing your mind later is meaningful
|
|
71
|
+
2. **Surprising without context**: a future reader will wonder "why did they do it this way?"
|
|
72
|
+
3. **The result of a real trade-off**: there were genuine alternatives and you picked one for specific reasons
|
|
73
|
+
|
|
74
|
+
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grill-with-docs
|
|
3
|
+
description: A relentless interview that turns a half-formed task into something an agent can execute blind, and writes down the terms and decisions it settles on the way. Use before writing a plan, a spec, or an issue somebody else will work from.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Grill with docs
|
|
7
|
+
|
|
8
|
+
Two disciplines on one job. Interview by the **grilling** method — a design tree
|
|
9
|
+
worked in rounds, the whole frontier asked at once, each question numbered and
|
|
10
|
+
carrying your recommended answer. Record what settles by the **domain-modeling**
|
|
11
|
+
method — the glossary and the decision records, written the moment a term
|
|
12
|
+
crystallises rather than at the end.
|
|
13
|
+
|
|
14
|
+
Both are AgentForge skills and both are in front of you: as `/agentforge:grilling`
|
|
15
|
+
and `/agentforge:domain-modeling` where the tool can invoke them, and inlined
|
|
16
|
+
below where it cannot. Do not restate their methods here — follow them.
|
|
17
|
+
|
|
18
|
+
What this file adds is the job the two are doing together.
|
|
19
|
+
|
|
20
|
+
## What the interview is for
|
|
21
|
+
|
|
22
|
+
The person you are asking is about to hand this work to something that cannot
|
|
23
|
+
ask them anything. A plan freezes when it is filed; an agent reads it a week
|
|
24
|
+
later on another machine with no memory of this conversation and no way to check
|
|
25
|
+
what was meant. Every question you fail to ask now becomes a guess made later by
|
|
26
|
+
something with less context than you have right now.
|
|
27
|
+
|
|
28
|
+
So the bar for a question is not "would this be interesting to know". It is
|
|
29
|
+
**would a different answer change what gets built**. Ask those relentlessly. Ask
|
|
30
|
+
nothing else.
|
|
31
|
+
|
|
32
|
+
## What not to ask
|
|
33
|
+
|
|
34
|
+
- **Anything you could find out yourself.** A question whose answer is in the
|
|
35
|
+
repository is a question you are making the human do your reading for. Go
|
|
36
|
+
read it. If finding out takes a while, ask the rest of the frontier while you
|
|
37
|
+
look.
|
|
38
|
+
- **Anything whose answer changes nothing.** Preferences you will not act on,
|
|
39
|
+
details below the level the plan operates at, confirmations of what they
|
|
40
|
+
already told you.
|
|
41
|
+
- **The same thing twice in different words.** If they have answered it, it is
|
|
42
|
+
settled; put it in the glossary rather than back in the queue.
|
|
43
|
+
|
|
44
|
+
## What to write down, and where
|
|
45
|
+
|
|
46
|
+
A term that took a round to pin down will take a round to pin down again next
|
|
47
|
+
month, with a different answer. That is the failure this half exists to prevent.
|
|
48
|
+
|
|
49
|
+
- **A term the human settles** goes in `CONTEXT.md` in the format that file
|
|
50
|
+
already uses — the definition and what not to call it. If two people in the
|
|
51
|
+
conversation were using one word for two things, that is the highest-value
|
|
52
|
+
entry you will write all day.
|
|
53
|
+
- **A decision with a live alternative** goes in `docs/adr/` — what was chosen,
|
|
54
|
+
what it was chosen over, and why. Not every decision: only the ones somebody
|
|
55
|
+
will otherwise reopen.
|
|
56
|
+
- **Nothing else.** You are interviewing, not implementing. Do not touch code,
|
|
57
|
+
and do not start a glossary for a project that has deliberately gone without
|
|
58
|
+
one.
|
|
59
|
+
|
|
60
|
+
Write these as they settle, not in a batch at the end. An interview that ends
|
|
61
|
+
early — and they often do, because the human has somewhere to be — should still
|
|
62
|
+
leave the terms it resolved behind it.
|
|
63
|
+
|
|
64
|
+
## When to stop
|
|
65
|
+
|
|
66
|
+
Stop at the first of these:
|
|
67
|
+
|
|
68
|
+
- **The frontier is empty.** Every branch visited, nothing silently assumed.
|
|
69
|
+
- **Nothing left would change the outcome.** Say so plainly and stop; do not
|
|
70
|
+
fill the round out to look thorough.
|
|
71
|
+
- **They tell you to.** Ending early is a legitimate answer, and what they have
|
|
72
|
+
already told you still counts. Plan with it rather than treating the interview
|
|
73
|
+
as void.
|
|
74
|
+
|
|
75
|
+
Then hand back what you have: what was asked, what was answered, and what you
|
|
76
|
+
wrote down.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grilling
|
|
3
|
+
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
|
|
7
|
+
|
|
8
|
+
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
|
|
9
|
+
|
|
10
|
+
Format a round like so:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
|
14
|
+
|
|
15
|
+
➡️ <your recommended answer>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
❓ **Q2** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
|
20
|
+
|
|
21
|
+
➡️ <your recommended answer>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each round the user answers reshapes the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
|
|
25
|
+
|
|
26
|
+
Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The _decisions_ are the user's: put each to them and wait.
|
|
27
|
+
|
|
28
|
+
The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: to-spec
|
|
3
|
+
description: "Turn the current conversation into a spec and publish it to the project issue tracker: no interview, just synthesis of what you've already discussed."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This skill takes the current conversation context and codebase understanding and produces a spec. Do NOT interview the user; just synthesize what you already know.
|
|
8
|
+
|
|
9
|
+
The issue tracker and triage label vocabulary should have been provided to you. If not, tell the user to run `/setup-matt-pocock-skills`.
|
|
10
|
+
|
|
11
|
+
## Process
|
|
12
|
+
|
|
13
|
+
1. Explore the repo to understand the current state of the codebase, if you haven't already. Use the project's domain glossary vocabulary throughout the spec, and respect any ADRs in the area you're touching.
|
|
14
|
+
|
|
15
|
+
2. Sketch out the seams at which you're going to test the feature. Existing seams should be preferred to new ones. Use the highest seam possible. If new seams are needed, propose them at the highest point you can. The fewer seams across the codebase, the better - the ideal number is one.
|
|
16
|
+
|
|
17
|
+
Check with the user that these seams match their expectations.
|
|
18
|
+
|
|
19
|
+
3. Write the spec using the template below, then publish it to the project issue tracker. Apply the `ready-for-agent` triage label - no need for additional triage.
|
|
20
|
+
|
|
21
|
+
<spec-template>
|
|
22
|
+
|
|
23
|
+
## Problem Statement
|
|
24
|
+
|
|
25
|
+
The problem that the user is facing, from the user's perspective.
|
|
26
|
+
|
|
27
|
+
## Solution
|
|
28
|
+
|
|
29
|
+
The solution to the problem, from the user's perspective.
|
|
30
|
+
|
|
31
|
+
## User Stories
|
|
32
|
+
|
|
33
|
+
A LONG, numbered list of user stories. Each user story should be in the format of:
|
|
34
|
+
|
|
35
|
+
1. As an <actor>, I want a <feature>, so that <benefit>
|
|
36
|
+
|
|
37
|
+
<user-story-example>
|
|
38
|
+
1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
|
|
39
|
+
</user-story-example>
|
|
40
|
+
|
|
41
|
+
This list of user stories should be extremely extensive and cover all aspects of the feature.
|
|
42
|
+
|
|
43
|
+
## Implementation Decisions
|
|
44
|
+
|
|
45
|
+
A list of implementation decisions that were made. This can include:
|
|
46
|
+
|
|
47
|
+
- The modules that will be built/modified
|
|
48
|
+
- The interfaces of those modules that will be modified
|
|
49
|
+
- Technical clarifications from the developer
|
|
50
|
+
- Architectural decisions
|
|
51
|
+
- Schema changes
|
|
52
|
+
- API contracts
|
|
53
|
+
- Specific interactions
|
|
54
|
+
|
|
55
|
+
Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
|
|
56
|
+
|
|
57
|
+
Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it within the relevant decision and note briefly that it came from a prototype. Trim to the decision-rich parts, not a working demo, just the important bits.
|
|
58
|
+
|
|
59
|
+
## Testing Decisions
|
|
60
|
+
|
|
61
|
+
A list of testing decisions that were made. Include:
|
|
62
|
+
|
|
63
|
+
- A description of what makes a good test (only test external behavior, not implementation details)
|
|
64
|
+
- Which modules will be tested
|
|
65
|
+
- Prior art for the tests (i.e. similar types of tests in the codebase)
|
|
66
|
+
|
|
67
|
+
## Out of Scope
|
|
68
|
+
|
|
69
|
+
A description of the things that are out of scope for this spec.
|
|
70
|
+
|
|
71
|
+
## Further Notes
|
|
72
|
+
|
|
73
|
+
Any further notes about the feature.
|
|
74
|
+
|
|
75
|
+
</spec-template>
|