@appchy/jarvis 0.1.36 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/config-change.mjs +1 -1
- package/bin/jarvis.mjs +8 -12
- package/bin/pre-tool-use.mjs +2 -2
- package/bin/session-start.mjs +1 -1
- package/bin/stop.mjs +1 -1
- package/bin/user-prompt-submit.mjs +1 -1
- package/dist/bin.js +10104 -37174
- package/dist/bin.js.map +1 -1
- package/dist/data/backends.mjs +469 -0
- package/dist/data/chunk-7REP35VA.mjs +462 -0
- package/dist/data/chunk-AKQQC5IT.mjs +1224 -0
- package/dist/data/chunk-AYOJSS2F.mjs +72 -0
- package/dist/data/chunk-RRJ6KKYL.mjs +42 -0
- package/dist/data/chunk-YWSWQEJN.mjs +138 -0
- package/dist/data/embedders.mjs +80 -0
- package/dist/data/finders.mjs +35 -0
- package/dist/data/index.mjs +137 -0
- package/dist/data/linkers.mjs +83 -0
- package/dist/data/mcp.mjs +2624 -0
- package/dist/data/persistences.mjs +8 -0
- package/dist/data/rerankers.mjs +52 -0
- package/dist/data/stores.mjs +38 -0
- package/dist/hooks/config-change.js +7 -29
- package/dist/hooks/config-change.js.map +1 -1
- package/dist/hooks/pre-tool-use.js +129 -32
- package/dist/hooks/pre-tool-use.js.map +1 -1
- package/dist/hooks/session-start.js +72 -37
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/stop.js +140 -32
- package/dist/hooks/stop.js.map +1 -1
- package/dist/hooks/user-prompt-submit.js +7 -29
- package/dist/hooks/user-prompt-submit.js.map +1 -1
- package/harness/assets/architecture-template.md +53 -0
- package/harness/assets/design-template.md +89 -0
- package/harness/assets/domains/architecture.md +43 -0
- package/harness/assets/domains/commercial.md +42 -0
- package/harness/assets/domains/design.md +42 -0
- package/harness/assets/domains/legal.md +43 -0
- package/harness/assets/domains/operations.md +39 -0
- package/harness/assets/domains/product.md +43 -0
- package/harness/assets/domains/quality.md +43 -0
- package/harness/assets/domains/security.md +44 -0
- package/harness/assets/domains/support.md +45 -0
- package/harness/assets/epic-template.md +85 -0
- package/harness/assets/feature-template.md +86 -0
- package/harness/assets/handoff-template.md +26 -0
- package/harness/assets/task-template.md +38 -0
- package/harness/assets/version-template.md +43 -0
- package/harness/harness/__init__.py +7 -0
- package/harness/harness/align.py +582 -0
- package/harness/harness/architecture.py +254 -0
- package/harness/harness/autonomy.py +374 -0
- package/harness/harness/branches.py +408 -0
- package/harness/harness/config.py +1482 -0
- package/harness/harness/coverage.py +199 -0
- package/harness/harness/epic.py +220 -0
- package/harness/harness/events.py +153 -0
- package/harness/harness/extend.py +99 -0
- package/harness/harness/frontmatter.py +218 -0
- package/harness/harness/gate.py +591 -0
- package/harness/harness/generate.py +267 -0
- package/harness/harness/git.py +775 -0
- package/harness/harness/ids.py +140 -0
- package/harness/harness/kickoff.py +231 -0
- package/harness/harness/lint.py +505 -0
- package/harness/harness/model.py +364 -0
- package/harness/harness/peers.py +187 -0
- package/harness/harness/product.py +29 -0
- package/harness/harness/registry.py +382 -0
- package/harness/harness/report.py +227 -0
- package/harness/harness/safety.py +387 -0
- package/harness/harness/scaffold.py +129 -0
- package/harness/harness/shard.py +63 -0
- package/harness/harness/shift.py +348 -0
- package/harness/harness/task.py +507 -0
- package/harness/harness/tree.py +258 -0
- package/harness/harness/version.py +305 -0
- package/harness/harness/wrap.py +217 -0
- package/harness/hooks/guard.py +259 -0
- package/harness/presets/appchy/PRESET.md +717 -0
- package/harness/presets/appchy/references/artifacts.md +539 -0
- package/harness/presets/appchy/references/graph.md +154 -0
- package/harness/presets/appchy/references/operations.md +444 -0
- package/harness/presets/appchy/references/research.md +216 -0
- package/harness/schema/work.config.schema.json +401 -0
- package/harness/test_work.py +5002 -0
- package/harness/work.py +534 -0
- package/package.json +34 -40
- package/bin/config-change.dev.mjs +0 -17
- package/bin/jarvis-dev.mjs +0 -30
- package/bin/pre-tool-use.dev.mjs +0 -23
- package/bin/session-start.dev.mjs +0 -17
- package/bin/stop.dev.mjs +0 -17
- package/bin/user-prompt-submit.dev.mjs +0 -17
- package/dev/bin.js +0 -38718
- package/dev/bin.js.map +0 -1
- package/dev/env.json +0 -1
- package/dev/hooks/config-change.js +0 -110
- package/dev/hooks/config-change.js.map +0 -1
- package/dev/hooks/pre-tool-use.js +0 -120
- package/dev/hooks/pre-tool-use.js.map +0 -1
- package/dev/hooks/session-start.js +0 -115
- package/dev/hooks/session-start.js.map +0 -1
- package/dev/hooks/stop.js +0 -112
- package/dev/hooks/stop.js.map +0 -1
- package/dev/hooks/user-prompt-submit.js +0 -111
- package/dev/hooks/user-prompt-submit.js.map +0 -1
- package/dist/env.json +0 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: domain
|
|
3
|
+
id: support
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Support — how users get unblocked
|
|
7
|
+
|
|
8
|
+
## What belongs here
|
|
9
|
+
|
|
10
|
+
Durable calls about **the stuck user** — what a failure must tell them, what
|
|
11
|
+
diagnostics exist, what self-service looks like, how something is escalated, and what
|
|
12
|
+
we promise about responsiveness.
|
|
13
|
+
|
|
14
|
+
The reason this is its own domain rather than a corner of operations: operations keeps
|
|
15
|
+
the *system* healthy, and a system can be perfectly healthy while a user is
|
|
16
|
+
completely stuck. An error message that is accurate and useless is not an
|
|
17
|
+
availability problem.
|
|
18
|
+
|
|
19
|
+
Its neighbours: [`operations/`](../operations/README.md) owns the running system.
|
|
20
|
+
[`product/`](../product/README.md) owns what the behaviour should have been.
|
|
21
|
+
[`design/`](../design/README.md) owns the wording and shape of what they see.
|
|
22
|
+
|
|
23
|
+
**Often empty in a young repo, and it ships anyway** — see the note in
|
|
24
|
+
[`security/`](../security/README.md).
|
|
25
|
+
|
|
26
|
+
## Non-goals
|
|
27
|
+
|
|
28
|
+
- **Whether the system is up.** `operations/`.
|
|
29
|
+
- **What the feature should do.** `product/`.
|
|
30
|
+
- **A single error message's copy.** `design/` owns tone; the rule about what a failure must always disclose belongs here.
|
|
31
|
+
- **One user's ticket.** Not durable direction.
|
|
32
|
+
|
|
33
|
+
## Rules
|
|
34
|
+
|
|
35
|
+
<!-- A durable rule lives in the domain that owns its KIND of call. Shape:
|
|
36
|
+
|
|
37
|
+
### <id> — the rule, in one line
|
|
38
|
+
enforced_by: the check that catches a violation — a command, a test, a lint
|
|
39
|
+
|
|
40
|
+
`enforced_by: judgement` is legal where a person really must decide, and is
|
|
41
|
+
counted separately rather than treated as enforcement. An empty one is a wish.
|
|
42
|
+
|
|
43
|
+
This section is EMPTY ON PURPOSE in a fresh repo. Do not seed it with invented
|
|
44
|
+
rules to make the domain look occupied — an empty domain is a signpost saying
|
|
45
|
+
where a call will go when you make one. -->
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: epic
|
|
3
|
+
created: {{CREATED}}
|
|
4
|
+
updated: {{CREATED}}
|
|
5
|
+
covers: {{COVERS}}
|
|
6
|
+
owner: {{OWNER}}
|
|
7
|
+
continues: {{CONTINUES}}
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# {{TITLE}}
|
|
11
|
+
|
|
12
|
+
<!-- An EPIC is the coherent goal you plan TOGETHER, and the folder that holds
|
|
13
|
+
the tasks delivering it. It is TEMPORARY by definition — `work.py release`
|
|
14
|
+
removes this file, because how the work was planned stops being true the
|
|
15
|
+
moment it ships. The folder stays as the grouping of what shipped; git
|
|
16
|
+
holds this text.
|
|
17
|
+
|
|
18
|
+
EPIC ⟂ FEATURE — the split that stops two overlapping groupings:
|
|
19
|
+
a FEATURE is permanent (the WHAT: B-nn, AC-nn, state:) and lives in
|
|
20
|
+
work/product/<feature>.md;
|
|
21
|
+
an EPIC is temporary (the HOW-NOW: the work moving one or more features
|
|
22
|
+
in one release). An epic MAY span features — that is precisely why it is
|
|
23
|
+
not a per-feature slice.
|
|
24
|
+
|
|
25
|
+
`covers:` names the feature acceptance criteria this epic moves, each
|
|
26
|
+
FEATURE-QUALIFIED (`profiles/AC-03`), because the span is the point. An
|
|
27
|
+
epic with no `covers:` is a lint: work that moves no stated criterion is
|
|
28
|
+
work nobody can tell is finished.
|
|
29
|
+
|
|
30
|
+
`owner:` is the ONE exemption from that, and it is not an escape hatch.
|
|
31
|
+
Some epics genuinely move no product criterion — a trailer, a test harness,
|
|
32
|
+
a migration — because nothing a user can do changes. Those answer to an
|
|
33
|
+
ORG-DOMAIN (`commercial`, `quality`, `operations`, …), and a domain hosts
|
|
34
|
+
rules rather than `AC-nn`, so there is nothing for `covers:` to name and the
|
|
35
|
+
lint could only be satisfied by claiming criteria the epic does not move.
|
|
36
|
+
Naming the domain here IS the stated finish line. It is checked: an `owner:`
|
|
37
|
+
that resolves to no domain exempts nothing. An epic owned by a FEATURE has
|
|
38
|
+
criteria available and is still expected to name them. -->
|
|
39
|
+
|
|
40
|
+
## Goal
|
|
41
|
+
|
|
42
|
+
<!-- What a user can newly do when this epic lands — one paragraph, product
|
|
43
|
+
language. Not a task list; the tasks are the folders beside this file. -->
|
|
44
|
+
|
|
45
|
+
## Plan
|
|
46
|
+
|
|
47
|
+
<!-- THE DESIGN. Written ONCE, here, for the whole goal — before the tasks are
|
|
48
|
+
cut — and NOT restated in any task. This is the entire reason the tier
|
|
49
|
+
exists: a task then EXECUTES, it does not re-analyse the system.
|
|
50
|
+
|
|
51
|
+
So the expensive thinking happens here exactly once:
|
|
52
|
+
- As-found — how the in-scope code works today, `path:line`, confirmed
|
|
53
|
+
by the blast-radius sweep. The blast-radius grind runs ONCE for the goal, not per task.
|
|
54
|
+
- Architecture — the target shape, the shared seams every task builds
|
|
55
|
+
against, and the alternatives weighed.
|
|
56
|
+
- The rules that constrain it — `work.py rules --task <t>` over
|
|
57
|
+
the union of the tasks' `code` regions; cite them so no task trips one.
|
|
58
|
+
- Slices — the task list, in landing order, with what each depends on.
|
|
59
|
+
Each cuts DOWN through every layer it needs and is shippable alone.
|
|
60
|
+
- The forward-compat pass (SKILL.md obligation 3) — run for the goal.
|
|
61
|
+
|
|
62
|
+
Link `path:line`; never paste code. Budget: As-found ≤40 lines,
|
|
63
|
+
Architecture ≤80 — the same caps a plan.md had, because this replaced it.
|
|
64
|
+
|
|
65
|
+
A task gets its own plan.md ONLY when pickup surfaces a call this document
|
|
66
|
+
did not settle — and that is a GAP here. Settle it and write it back up, so
|
|
67
|
+
the next task inherits the answer instead of re-deriving it too. -->
|
|
68
|
+
|
|
69
|
+
## Governance this implies
|
|
70
|
+
|
|
71
|
+
<!-- PLAN-THEN-APPLY. `work/product/**`, `work/architecture/**` and
|
|
72
|
+
`work/quality/**` describe WHAT IS TRUE NOW — never a proposal. So the
|
|
73
|
+
domain-doc edits this epic will make are STATED HERE and applied when the
|
|
74
|
+
work lands: with the code, or not at all.
|
|
75
|
+
|
|
76
|
+
One line each, naming the owner file and the change. e.g.
|
|
77
|
+
- product/profiles.md — AC-09..AC-11 added for the org tier
|
|
78
|
+
- architecture/<system>.md — <id>: a principal is a person
|
|
79
|
+
OR an organization
|
|
80
|
+
If this epic implies no governance change, say so explicitly. -->
|
|
81
|
+
|
|
82
|
+
## Non-goals
|
|
83
|
+
|
|
84
|
+
<!-- What this epic deliberately leaves for later, so its boundary can't creep
|
|
85
|
+
into the next release. One line each. -->
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: feature
|
|
3
|
+
state: {{STATE}}
|
|
4
|
+
# depends_on: [other-feature] # optional — an enabler feature this one needs
|
|
5
|
+
# first; a bare <feature>, existence-lint only
|
|
6
|
+
log:
|
|
7
|
+
- {{DATE}} {{STATE}} (created)
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!-- Naming: title this feature's folder as the OUTCOME the user gets, in plain
|
|
11
|
+
language — not the implementation, not a codename. If state is `idea`,
|
|
12
|
+
name it as the user's PROBLEM instead (e.g. `slow-onboarding`, not
|
|
13
|
+
`add-quickstart-wizard`) — rename once it graduates past idea. Granularity:
|
|
14
|
+
one feature = the smallest thing you'd ship and tell a user about on its
|
|
15
|
+
own; needs "and" three times or several pieces must ship together first →
|
|
16
|
+
split it or call it what it is, an epic, and give each shippable slice its
|
|
17
|
+
own `<feature>.md`.
|
|
18
|
+
|
|
19
|
+
`state`: idea | defined | building | shipped | retired — the durable
|
|
20
|
+
lifecycle, EVIDENCE-DERIVED (see SKILL.md §Feature state), not a mood:
|
|
21
|
+
idea — the feature exists but has open product questions
|
|
22
|
+
defined — Problem + Stories + Behaviour + Acceptance criteria complete
|
|
23
|
+
building — at least one in-progress task targets it (owner: link)
|
|
24
|
+
shipped — every in-scope AC has passing evidence + a release reference
|
|
25
|
+
retired — a durable product rule says the behaviour is gone
|
|
26
|
+
|
|
27
|
+
`log`: the state TIMELINE — append one dated line per state transition,
|
|
28
|
+
newest last, with the evidence in parentheses (the task that flipped it,
|
|
29
|
+
the founder review, the release ref). Re-openings are transitions too:
|
|
30
|
+
adding new B-/AC- items to a defined/shipped feature appends a line
|
|
31
|
+
(e.g. `2026-08-02 defined (re-opened: AC-08 added)`) so the current
|
|
32
|
+
standing is always visible. Never rewrite old lines.
|
|
33
|
+
|
|
34
|
+
THIS FILE IS THE DURABLE SOURCE OF TRUTH for what the app should do. It is
|
|
35
|
+
independent of the code: if the code disagrees, the code is what's wrong
|
|
36
|
+
(SKILL.md §The spec may say the code is wrong). Product language only —
|
|
37
|
+
no file paths, no code. -->
|
|
38
|
+
|
|
39
|
+
## Problem
|
|
40
|
+
|
|
41
|
+
<!-- What's wrong, or what's needed — in product language. No file paths, no code. -->
|
|
42
|
+
|
|
43
|
+
## Stories
|
|
44
|
+
|
|
45
|
+
<!-- The value/context lens — NOT the container. A user story frames actor +
|
|
46
|
+
goal + value; a job story frames situation + motivation + outcome. Pick
|
|
47
|
+
whichever fits; each story points at the behaviour rules / acceptance
|
|
48
|
+
criteria it frames (by id). One or a few — this is intent, not a backlog. -->
|
|
49
|
+
|
|
50
|
+
As a <role>, I want <capability>, so that <outcome>. → B-01, AC-01
|
|
51
|
+
<!-- or: When <situation>, I want <motivation>, so I can <outcome>. → B-02 -->
|
|
52
|
+
|
|
53
|
+
## Behaviour
|
|
54
|
+
|
|
55
|
+
<!-- B-nn: observable rules — what the app DOES, phrased as observable outcomes
|
|
56
|
+
independent of how it's built. These are the durable "what it should do"
|
|
57
|
+
that buggy code cannot redefine. A wireframe (this feature's own
|
|
58
|
+
wireframes/ folder, via the artifact-design skill) is linked here once one
|
|
59
|
+
exists — link it, don't restate it. IDs are unique within THIS feature. -->
|
|
60
|
+
|
|
61
|
+
- B-01: <an observable rule>
|
|
62
|
+
|
|
63
|
+
## Acceptance criteria
|
|
64
|
+
|
|
65
|
+
<!-- AC-nn: checkable conditions that bound "done" — observable input/condition
|
|
66
|
+
→ observable output, including failure and edge behaviour. Plain IDed
|
|
67
|
+
bullets by default; use Given/When/Then ONLY where a gnarly multi-branch
|
|
68
|
+
rule genuinely earns it (ceremony everywhere ossifies — Cucumber's own
|
|
69
|
+
warning). These are the TRACE UNIT: a task's `owner:` cites the AC ids it
|
|
70
|
+
implements, and a test declares them with `covers("<feature>/AC-nn")` or a
|
|
71
|
+
Playwright `{ tag: ["@<feature>/AC-nn"] }` — never a comment, which would go on
|
|
72
|
+
claiming a criterion after the test is renamed or deleted. IDs unique within
|
|
73
|
+
this feature; never reuse an id after it ships. -->
|
|
74
|
+
|
|
75
|
+
- [ ] AC-01: <observable condition → observable outcome (+ failure/edge)>
|
|
76
|
+
|
|
77
|
+
## Non-goals
|
|
78
|
+
|
|
79
|
+
<!-- What this feature explicitly does NOT do — bounds the spec so scope can't
|
|
80
|
+
silently creep. One line each. Omit the heading only if genuinely none. -->
|
|
81
|
+
|
|
82
|
+
- <a thing this feature deliberately doesn't do>
|
|
83
|
+
|
|
84
|
+
<!-- No `tasks:` list — which tasks serve this feature is always a query over
|
|
85
|
+
task.md's `owner:` field, never hand-maintained. Links out (roadmap
|
|
86
|
+
placement, tests, shipped release) go inline where relevant, as pointers. -->
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# handoff — {{TITLE}}
|
|
2
|
+
|
|
3
|
+
<!-- The live session brief — the one file a fresh session reads to know where
|
|
4
|
+
things stand. HARD CAP 80 lines: when over, move durable facts into
|
|
5
|
+
plan.md / the owning domain's rules and drop the oldest log entries. -->
|
|
6
|
+
|
|
7
|
+
**Status:** <one line — where the task is right now. The ONLY home for status.>
|
|
8
|
+
**NEXT:** <one line — the single next action to take.>
|
|
9
|
+
|
|
10
|
+
## Read order
|
|
11
|
+
|
|
12
|
+
<!-- The files a cold session reads, in order. e.g.
|
|
13
|
+
task.md → plan.md → the rules its domain owns → wireframes/ui.md -->
|
|
14
|
+
|
|
15
|
+
## Log
|
|
16
|
+
|
|
17
|
+
<!-- Dated, LATEST FIRST. The top line is always the freshest truth.
|
|
18
|
+
≤3 lines per entry. Pruning removes from the bottom. -->
|
|
19
|
+
|
|
20
|
+
- {{CREATED}} <what happened / what this session set up>
|
|
21
|
+
|
|
22
|
+
## Decisions
|
|
23
|
+
|
|
24
|
+
<!-- Small, task-local calls as plain bullets. A durable decision is promoted
|
|
25
|
+
to the domain that owns it with the next free number, and reduced HERE to a
|
|
26
|
+
pointer: `<id>: <title>`. Rationale never lives in two places. -->
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
priority: {{PRIORITY}}
|
|
3
|
+
depends_on: {{DEPENDS_ON}}
|
|
4
|
+
created: {{CREATED}}
|
|
5
|
+
updated: {{CREATED}}
|
|
6
|
+
# `sessions:` and `completed:` are added automatically by work.py — never written by hand.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# {{TITLE}}
|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
|
|
13
|
+
<!-- What is wrong, or what is needed. Enough to start cold with no prior
|
|
14
|
+
conversation — one or two paragraphs. -->
|
|
15
|
+
|
|
16
|
+
## Context & findings
|
|
17
|
+
|
|
18
|
+
<!-- Investigation notes: root cause, relevant files as path:line, what was
|
|
19
|
+
ruled out. Leave empty until investigated. -->
|
|
20
|
+
|
|
21
|
+
## Acceptance criteria
|
|
22
|
+
|
|
23
|
+
- [ ] <!-- A concrete, checkable outcome. Tests trace back to these. -->
|
|
24
|
+
|
|
25
|
+
## Open questions
|
|
26
|
+
|
|
27
|
+
- <!-- An unknown to resolve when the task is picked up. -->
|
|
28
|
+
|
|
29
|
+
<!-- There is NO length cap on this file. A brief is read by a session starting
|
|
30
|
+
cold, and the findings, dead ends and warnings that make that cheap are
|
|
31
|
+
exactly what a line budget deletes. Say what the next reader needs.
|
|
32
|
+
|
|
33
|
+
What a queued brief must NOT become is a competing PLAN: no `## Approach`
|
|
34
|
+
until one is agreed, no design or analysis until pickup (that lives in the
|
|
35
|
+
epic's §Plan, or plan.md in the rare case the task owns its own). Once a
|
|
36
|
+
plan.md exists, an `## Approach` here collapses to a single line:
|
|
37
|
+
`Approach → plan.md`. The artifact lint catches that by looking for the
|
|
38
|
+
FILES, which is the failure a length rule was only ever a proxy for. -->
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
created: {{CREATED}}
|
|
3
|
+
updated: {{CREATED}}
|
|
4
|
+
order: {{ORDER}}
|
|
5
|
+
outcome: {{OUTCOME}}
|
|
6
|
+
start: {{START}}
|
|
7
|
+
end: {{END}}
|
|
8
|
+
target: {{TARGET}}
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# {{TITLE}}
|
|
12
|
+
|
|
13
|
+
<!-- A VERSION IS A RELEASE. One rule follows from that and it is enforced: it
|
|
14
|
+
states a user-visible `outcome:` — one line on what someone can newly DO when
|
|
15
|
+
it ships. If you cannot say that, this is an epic, not a release.
|
|
16
|
+
|
|
17
|
+
KEEP IT SMALL. A cut should finish in days, not months. Several may be open
|
|
18
|
+
at once and the sequencing is yours; what the harness will not do is let a
|
|
19
|
+
version close with unfinished work in it, so a cut that grows past what you
|
|
20
|
+
can finish is a cut that never closes.
|
|
21
|
+
|
|
22
|
+
Its EPICS are the folders beside this file — each the coherent goal it
|
|
23
|
+
planned together. They are removed at release; this file is the permanent
|
|
24
|
+
record. -->
|
|
25
|
+
|
|
26
|
+
## Goal
|
|
27
|
+
|
|
28
|
+
<!-- The capability this release delivers — one or two paragraphs. The
|
|
29
|
+
user-facing "what's new" the version answers, not a task list. Expands the
|
|
30
|
+
one-line `outcome:` above; never contradicts it. -->
|
|
31
|
+
|
|
32
|
+
## Scope
|
|
33
|
+
|
|
34
|
+
<!-- The tasks committed to this cut. Use the README backlog table for the
|
|
35
|
+
live list — this section is for the narrative reasoning (why these slices
|
|
36
|
+
together make a coherent release). LINK the feature stories this cut
|
|
37
|
+
serves (work/product/**.md §Stories) — version stories.md is
|
|
38
|
+
retired; behaviour is owned per-feature, referenced here, never restated. -->
|
|
39
|
+
|
|
40
|
+
## Release notes
|
|
41
|
+
|
|
42
|
+
<!-- The shipping summary the user reads when the version ships. Drafted as the
|
|
43
|
+
cut is decided; finalised at `work.py release`. -->
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""The /work harness, split by noun — one module per command noun.
|
|
2
|
+
|
|
3
|
+
The CLI entry is `work.py`, which only dispatches. `tree`, `frontmatter`,
|
|
4
|
+
`model` and `registry` are the reusable layer; `lint`, `align` and `generate`
|
|
5
|
+
produce the derived facts; the rest are one module per command noun.
|
|
6
|
+
Governed by `work/architecture/harness.md`.
|
|
7
|
+
"""
|