@svayam-opensource/prj 0.5.3 → 0.5.4
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/README.md +21 -7
- package/package.json +1 -2
- package/scripts/bump-version.sh +47 -0
- package/scripts/validate/check_version_sync.py +85 -0
- package/scripts/validate/run.py +2 -0
- package/agent/harness-manifest.yaml +0 -225
- package/agent/session-protocol.md +0 -116
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ of GitHub, under your organization's policy. You run `prj` and follow the menus;
|
|
|
9
9
|
|
|
10
10
|
## The framework has two components
|
|
11
11
|
|
|
12
|
-
 and Governance Actions (prj, the client that acts) — both operating on your governance workspace; adopt Content first, then act with prj.](https://cdn.jsdelivr.net/npm/@svayam-opensource/prj@latest/assets/readme/two-components.svg)
|
|
13
13
|
|
|
14
14
|
1. **Governance Content** — the policies, knowledge structure, agent harness, and
|
|
15
15
|
scaffolding that define *how* your org governs agentic work. **This lives in the
|
|
@@ -37,15 +37,29 @@ Runtime prerequisites (not npm dependencies — `prj` is bash): `bash`, `git`,
|
|
|
37
37
|
`gh` (authenticated), `yq`, `python3`. On Windows, run inside **Git Bash**.
|
|
38
38
|
|
|
39
39
|
### Sequencing — Content first, then Actions
|
|
40
|
-

|
|
41
|
+
`prj` acts *on* a configured governance workspace. **Which path applies to you
|
|
42
|
+
depends on whether your org has already adopted the framework:**
|
|
43
|
+
|
|
44
|
+
- **First-time adopter — you're the governance owner/admin for your org.**
|
|
45
|
+
Set up **Governance Content first** from the
|
|
46
|
+
[template repo](https://github.com/svayam-opensource/governed-agentic-dev-framework)
|
|
47
|
+
(clone it, run its `setup.sh`, fill in `org-config.yaml`), **then** install and
|
|
48
|
+
run `prj`. You are the one who copies and tailors the content.
|
|
49
|
+
- **Your org already runs the framework — you're a developer/contributor.**
|
|
50
|
+
**Do not copy the template or re-run setup.** Your governance admin has already
|
|
51
|
+
adopted and customized the content. Just `npm i -g @svayam-opensource/prj`, get
|
|
52
|
+
the **workspace location from your governance admin**, and run `prj` from inside
|
|
53
|
+
it (or point `$ADF_WORKSPACE` at it). For anything about the governance content
|
|
54
|
+
itself — policies, knowledge, the agent harness, who owns what — **contact your
|
|
55
|
+
org's governance admin**, not this README.
|
|
56
|
+
|
|
57
|
+
Run `prj` from anywhere inside the workspace (it finds it via `$ADF_WORKSPACE` or
|
|
58
|
+
the nearest `org-config.yaml`).
|
|
45
59
|
|
|
46
60
|
### Dependencies — GitHub is the substrate
|
|
47
61
|
`prj` keeps no separate database. Every fact lives in GitHub:
|
|
48
|
-
, Issues (units of work, the anchor issue carries ownership), Repos (where code lives, derived from the board's issues), and GitHub Actions (CI gates that enforce the policy).](https://cdn.jsdelivr.net/npm/@svayam-opensource/prj@latest/assets/readme/dependencies.svg)
|
|
49
63
|
|
|
50
64
|
### Journeys — *how do I…?*
|
|
51
65
|
You don't need the command list. Run **`prj`** and follow the menu (every step is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svayam-opensource/prj",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Governed Agentic Development Framework CLI (prj). A bash CLI wrapped for npm; operates on a governance workspace resolved via $ADF_WORKSPACE or the nearest org-config.yaml. Runtime prerequisites (not npm deps): bash, git, gh, yq, python3 (use Git Bash on Windows).",
|
|
5
5
|
"bin": {
|
|
6
6
|
"prj": "bin/prj"
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"prj",
|
|
10
10
|
"bin/",
|
|
11
11
|
"setup.sh",
|
|
12
|
-
"agent/",
|
|
13
12
|
"scripts/*.sh",
|
|
14
13
|
"scripts/validate/*.py",
|
|
15
14
|
"assets/readme/*.svg"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# bump-version.sh <x.y.z[-pre]>
|
|
4
|
+
#
|
|
5
|
+
# Single action that writes the release version into the three internal places
|
|
6
|
+
# that must agree:
|
|
7
|
+
#
|
|
8
|
+
# 1. package.json -> "version"
|
|
9
|
+
# 2. framework/VERSION
|
|
10
|
+
# 3. .framework-version
|
|
11
|
+
#
|
|
12
|
+
# The README diagram images are served by jsDelivr from the published npm
|
|
13
|
+
# tarball via the floating `@latest` tag, so they are NOT version-pinned and
|
|
14
|
+
# need no edit here. scripts/validate/check_version_sync.py enforces all of
|
|
15
|
+
# this in CI and in the Jenkins publish gate.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# scripts/bump-version.sh 0.5.4
|
|
19
|
+
# then: review `git diff`, commit, push, trigger the publish webhook.
|
|
20
|
+
#
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
new="${1:-}"
|
|
24
|
+
if [ -z "$new" ]; then
|
|
25
|
+
echo "usage: scripts/bump-version.sh <x.y.z>" >&2
|
|
26
|
+
exit 2
|
|
27
|
+
fi
|
|
28
|
+
case "$new" in
|
|
29
|
+
[0-9]*.[0-9]*.[0-9]*) : ;;
|
|
30
|
+
*) echo "error: '$new' is not a version (expected x.y.z)" >&2; exit 2 ;;
|
|
31
|
+
esac
|
|
32
|
+
|
|
33
|
+
root="$(cd "$(dirname "$0")/.." && pwd)"
|
|
34
|
+
cd "$root"
|
|
35
|
+
|
|
36
|
+
# package.json: targeted replace of the top-level "version" value only — keeps
|
|
37
|
+
# the file's existing formatting intact (no full re-serialize).
|
|
38
|
+
NEW="$new" perl -0pi -e 's/("version"\s*:\s*")[^"]*(")/$1.$ENV{NEW}.$2/e' package.json
|
|
39
|
+
printf '%s\n' "$new" > framework/VERSION
|
|
40
|
+
printf '%s\n' "$new" > .framework-version
|
|
41
|
+
|
|
42
|
+
echo "bumped -> $new"
|
|
43
|
+
echo " package.json $(grep -m1 '"version"' package.json | tr -d ' ,')"
|
|
44
|
+
echo " framework/VERSION $(cat framework/VERSION)"
|
|
45
|
+
echo " .framework-version $(cat .framework-version)"
|
|
46
|
+
echo
|
|
47
|
+
echo "next: review 'git diff', commit + push, then trigger the publish webhook."
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Version-sync validator.
|
|
4
|
+
|
|
5
|
+
The package version lives in three places that MUST agree, or installs and the
|
|
6
|
+
downgrade guard misbehave:
|
|
7
|
+
|
|
8
|
+
1. package.json -> "version" (the source of truth)
|
|
9
|
+
2. framework/VERSION (shipped framework version)
|
|
10
|
+
3. .framework-version (install marker read by setup.sh on upgrade)
|
|
11
|
+
|
|
12
|
+
The README's diagram images are served by jsDelivr out of the published npm
|
|
13
|
+
tarball, referenced with the FLOATING `@latest` tag — so they are deliberately
|
|
14
|
+
NOT version-pinned and need no bump. This check also guards that nobody
|
|
15
|
+
accidentally re-pins them to an exact version (which would silently go stale on
|
|
16
|
+
the next release).
|
|
17
|
+
|
|
18
|
+
Bump all three with: scripts/bump-version.sh <x.y.z>
|
|
19
|
+
|
|
20
|
+
Run standalone (the Jenkins publish gate does this):
|
|
21
|
+
python3 scripts/validate/check_version_sync.py [REPO_ROOT]
|
|
22
|
+
Exits 0 on pass, 1 on drift.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
import re
|
|
27
|
+
import sys
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
# jsDelivr URLs for THIS package in the README. Capture the version spec.
|
|
31
|
+
_README_PIN_RE = re.compile(
|
|
32
|
+
r"cdn\.jsdelivr\.net/npm/@svayam-opensource/prj@([^/]+)/"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def check_version_sync(repo_root: Path) -> list[str]:
|
|
37
|
+
errors: list[str] = []
|
|
38
|
+
|
|
39
|
+
pkg_path = repo_root / "package.json"
|
|
40
|
+
if not pkg_path.exists():
|
|
41
|
+
return ["package.json not found"]
|
|
42
|
+
try:
|
|
43
|
+
version = (json.loads(pkg_path.read_text()).get("version") or "").strip()
|
|
44
|
+
except json.JSONDecodeError as e:
|
|
45
|
+
return [f"package.json does not parse: {e}"]
|
|
46
|
+
if not version:
|
|
47
|
+
return ["package.json: no 'version' field"]
|
|
48
|
+
|
|
49
|
+
# The two plain-text version files must equal package.json exactly.
|
|
50
|
+
for rel in ("framework/VERSION", ".framework-version"):
|
|
51
|
+
p = repo_root / rel
|
|
52
|
+
if not p.exists():
|
|
53
|
+
errors.append(f"{rel}: missing (expected to equal package.json {version})")
|
|
54
|
+
continue
|
|
55
|
+
got = p.read_text().strip()
|
|
56
|
+
if got != version:
|
|
57
|
+
errors.append(f"{rel}: {got!r} != package.json {version!r}")
|
|
58
|
+
|
|
59
|
+
# README diagram URLs must stay on @latest (floating), never an exact pin.
|
|
60
|
+
readme = repo_root / "README.md"
|
|
61
|
+
if readme.exists():
|
|
62
|
+
for spec in _README_PIN_RE.findall(readme.read_text()):
|
|
63
|
+
if spec != "latest":
|
|
64
|
+
errors.append(
|
|
65
|
+
f"README.md: jsDelivr URL is pinned to @{spec}; use @latest "
|
|
66
|
+
f"(diagram assets ship in the package and float with the release)"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return errors
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main() -> int:
|
|
73
|
+
repo_root = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
|
74
|
+
errors = check_version_sync(repo_root)
|
|
75
|
+
if errors:
|
|
76
|
+
print(f"[FAIL] version-sync ({len(errors)} error{'s' if len(errors) != 1 else ''}):")
|
|
77
|
+
for e in errors:
|
|
78
|
+
print(f" - {e}")
|
|
79
|
+
return 1
|
|
80
|
+
print("[PASS] version-sync")
|
|
81
|
+
return 0
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
sys.exit(main())
|
package/scripts/validate/run.py
CHANGED
|
@@ -27,6 +27,7 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|
|
27
27
|
from check_knowledge import check_knowledge # noqa: E402
|
|
28
28
|
from check_secrets import check_secrets # noqa: E402
|
|
29
29
|
from check_protocol import check_protocol # noqa: E402
|
|
30
|
+
from check_version_sync import check_version_sync # noqa: E402
|
|
30
31
|
|
|
31
32
|
try:
|
|
32
33
|
import yaml
|
|
@@ -355,6 +356,7 @@ CHECKS = [
|
|
|
355
356
|
("knowledge-org", check_knowledge),
|
|
356
357
|
("secrets", check_secrets),
|
|
357
358
|
("protocol", check_protocol),
|
|
359
|
+
("version-sync", check_version_sync),
|
|
358
360
|
]
|
|
359
361
|
|
|
360
362
|
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
# Harness manifest — drives scripts/render-harness.sh
|
|
2
|
-
# Canonical protocol: agent/session-protocol.md + agent.md
|
|
3
|
-
# Spec: docs/design/agent-context-assembly-spec.md §3.3, Appendix C, Appendix D
|
|
4
|
-
#
|
|
5
|
-
# Do not hand-edit generated install paths listed under harnesses[].path when
|
|
6
|
-
# generated: true. Run ./scripts/render-harness.sh after editing session-protocol.
|
|
7
|
-
|
|
8
|
-
version: 1
|
|
9
|
-
|
|
10
|
-
canonical:
|
|
11
|
-
session_protocol: agent/session-protocol.md
|
|
12
|
-
org_entrypoint: framework/agent.md
|
|
13
|
-
adopter_marker: "<!-- ADOPTER_C03_EXTENSIONS -->"
|
|
14
|
-
|
|
15
|
-
# Delivery tiers (see spec Appendix D)
|
|
16
|
-
# import — file expand at launch (@import); Claude Code only today
|
|
17
|
-
# generate_auto — render-harness embeds protocol; tool auto-loads install path
|
|
18
|
-
# generate_manual— render-harness embeds protocol; developer must invoke (--read)
|
|
19
|
-
# fallback — no repo convention; paste ./prj context assemble output
|
|
20
|
-
|
|
21
|
-
tiers:
|
|
22
|
-
import:
|
|
23
|
-
description: Expand canonical files into startup context at tool launch
|
|
24
|
-
generate_auto:
|
|
25
|
-
description: Generated install path auto-loaded by the tool
|
|
26
|
-
generate_manual:
|
|
27
|
-
description: Generated file exists but developer must pass a flag or slash-command
|
|
28
|
-
fallback:
|
|
29
|
-
description: No install path; use kickoff prompt + transcript reads
|
|
30
|
-
|
|
31
|
-
generated_banner: "<!-- GENERATED FROM agent/session-protocol.md — do not edit; run ./scripts/render-harness.sh -->"
|
|
32
|
-
|
|
33
|
-
harnesses:
|
|
34
|
-
# ── Tier: import ──────────────────────────────────────────────────────────
|
|
35
|
-
- id: claude-code
|
|
36
|
-
tool: Claude Code
|
|
37
|
-
status: active
|
|
38
|
-
tier: import
|
|
39
|
-
path: framework/CLAUDE.md
|
|
40
|
-
generated: false
|
|
41
|
-
seed_copy: true
|
|
42
|
-
per_project_path: projects/{project_id}/CLAUDE.md
|
|
43
|
-
per_project_template: |
|
|
44
|
-
@../../agent/session-protocol.md
|
|
45
|
-
@agent.md
|
|
46
|
-
|
|
47
|
-
<!-- ADOPTER_C03_EXTENSIONS -->
|
|
48
|
-
verify: "Run /memory — must list CLAUDE.md and imported agent files"
|
|
49
|
-
notes: |
|
|
50
|
-
Claude does not read AGENTS.md unless @AGENTS.md is added.
|
|
51
|
-
First @import shows approval dialog once per project.
|
|
52
|
-
|
|
53
|
-
# ── Tier: generate_auto ───────────────────────────────────────────────────
|
|
54
|
-
- id: cursor
|
|
55
|
-
tool: Cursor
|
|
56
|
-
status: active
|
|
57
|
-
tier: generate_auto
|
|
58
|
-
path: framework/.cursor/rules/agent.mdc
|
|
59
|
-
generated: true
|
|
60
|
-
seed_copy: true
|
|
61
|
-
template: cursor-mdc
|
|
62
|
-
template_extra:
|
|
63
|
-
description: "Agentic Development Framework — session-start protocol (POL-113..117)"
|
|
64
|
-
globs: '["**/*"]'
|
|
65
|
-
alwaysApply: true
|
|
66
|
-
verify: "Cursor Settings → Rules — agent.mdc must show Always"
|
|
67
|
-
notes: |
|
|
68
|
-
Injected on every Chat/Agent/Composer turn when alwaysApply is true.
|
|
69
|
-
Inline Edit (Cmd+K) may not receive full rules.
|
|
70
|
-
|
|
71
|
-
- id: openai-codex
|
|
72
|
-
tool: OpenAI Codex
|
|
73
|
-
status: active
|
|
74
|
-
tier: generate_auto
|
|
75
|
-
path: framework/AGENTS.md
|
|
76
|
-
generated: true
|
|
77
|
-
seed_copy: true
|
|
78
|
-
template: markdown-plain
|
|
79
|
-
verify: "First message — ask agent to summarize session protocol"
|
|
80
|
-
notes: "Plain markdown; Codex CLI, Codex Web, ChatGPT coding mode."
|
|
81
|
-
|
|
82
|
-
- id: gemini-code-assist
|
|
83
|
-
tool: Gemini Code Assist
|
|
84
|
-
status: active
|
|
85
|
-
tier: generate_auto
|
|
86
|
-
path: framework/.gemini/styleguide.md
|
|
87
|
-
generated: true
|
|
88
|
-
seed_copy: true
|
|
89
|
-
template: markdown-plain
|
|
90
|
-
verify: "First message — ask what styleguide/rules were loaded"
|
|
91
|
-
notes: |
|
|
92
|
-
Convention name is styleguide; content is session protocol.
|
|
93
|
-
Re-check Google docs when extension updates.
|
|
94
|
-
|
|
95
|
-
- id: github-copilot
|
|
96
|
-
tool: GitHub Copilot
|
|
97
|
-
status: active
|
|
98
|
-
tier: generate_auto
|
|
99
|
-
path: framework/.github/copilot-instructions.md
|
|
100
|
-
generated: true
|
|
101
|
-
seed_copy: true
|
|
102
|
-
template: markdown-plain
|
|
103
|
-
verify: "Copilot assist on a repo file — ask it to state write restrictions"
|
|
104
|
-
notes: |
|
|
105
|
-
Edit-time assist, not a full agent session. Weaker C01 gate than Cursor/Claude.
|
|
106
|
-
Same folder holds GitHub Actions — do not mix CI config into instructions.
|
|
107
|
-
|
|
108
|
-
- id: windsurf
|
|
109
|
-
tool: Windsurf
|
|
110
|
-
status: active
|
|
111
|
-
tier: generate_auto
|
|
112
|
-
path: framework/.windsurf/rules/agent.md
|
|
113
|
-
generated: true
|
|
114
|
-
seed_copy: true
|
|
115
|
-
template: markdown-plain
|
|
116
|
-
verify: "First message — confirm rules loaded"
|
|
117
|
-
|
|
118
|
-
- id: cline
|
|
119
|
-
tool: Cline / Roo Code
|
|
120
|
-
status: active
|
|
121
|
-
tier: generate_auto
|
|
122
|
-
path: framework/.clinerules/agent.md
|
|
123
|
-
generated: true
|
|
124
|
-
seed_copy: true
|
|
125
|
-
template: markdown-plain
|
|
126
|
-
verify: "Open projects/{project_id}/ as workspace; confirm rules on startup"
|
|
127
|
-
notes: "Supports nested .clinerules/ per subdirectory."
|
|
128
|
-
|
|
129
|
-
- id: continue
|
|
130
|
-
tool: Continue.dev
|
|
131
|
-
status: active
|
|
132
|
-
tier: generate_auto
|
|
133
|
-
path: framework/.continue/rules.md
|
|
134
|
-
generated: true
|
|
135
|
-
seed_copy: true
|
|
136
|
-
template: markdown-plain
|
|
137
|
-
verify: "First message — confirm system rules loaded"
|
|
138
|
-
notes: "Complements .continue/config.yaml context providers."
|
|
139
|
-
|
|
140
|
-
# ── Tier: generate_manual ─────────────────────────────────────────────────
|
|
141
|
-
- id: aider
|
|
142
|
-
tool: Aider
|
|
143
|
-
status: active
|
|
144
|
-
tier: generate_manual
|
|
145
|
-
path: framework/CONVENTIONS.md
|
|
146
|
-
generated: true
|
|
147
|
-
seed_copy: true
|
|
148
|
-
template: markdown-plain
|
|
149
|
-
invoke: "aider --read CONVENTIONS.md …"
|
|
150
|
-
verify: "Confirm CONVENTIONS.md in aider context at session start"
|
|
151
|
-
|
|
152
|
-
# ── Tier: fallback (registered, not generated) ────────────────────────────
|
|
153
|
-
- id: chatgpt-web
|
|
154
|
-
tool: ChatGPT (web) / custom GPT
|
|
155
|
-
status: registered
|
|
156
|
-
tier: fallback
|
|
157
|
-
path: null
|
|
158
|
-
verify: "Paste kickoff prompt from DEVELOPER_GUIDE §3"
|
|
159
|
-
notes: "No repo-local auto-load."
|
|
160
|
-
|
|
161
|
-
- id: jetbrains-ai
|
|
162
|
-
tool: JetBrains AI Assistant
|
|
163
|
-
status: planned
|
|
164
|
-
tier: generate_auto
|
|
165
|
-
path: .junie/guidelines.md
|
|
166
|
-
generated: true
|
|
167
|
-
seed_copy: false
|
|
168
|
-
template: markdown-plain
|
|
169
|
-
notes: "Verify path against JetBrains docs before enabling."
|
|
170
|
-
|
|
171
|
-
- id: amazon-q
|
|
172
|
-
tool: Amazon Q Developer
|
|
173
|
-
status: planned
|
|
174
|
-
tier: generate_auto
|
|
175
|
-
path: .amazonq/rules.md
|
|
176
|
-
generated: true
|
|
177
|
-
seed_copy: false
|
|
178
|
-
template: markdown-plain
|
|
179
|
-
notes: "Path TBD — confirm with AWS docs before enabling."
|
|
180
|
-
|
|
181
|
-
- id: sourcegraph-cody
|
|
182
|
-
tool: Sourcegraph Cody
|
|
183
|
-
status: planned
|
|
184
|
-
tier: generate_auto
|
|
185
|
-
path: .sourcegraph/cody-rules.md
|
|
186
|
-
generated: true
|
|
187
|
-
seed_copy: false
|
|
188
|
-
template: markdown-plain
|
|
189
|
-
notes: "Path TBD."
|
|
190
|
-
|
|
191
|
-
# Templates (consumed by render-harness.sh)
|
|
192
|
-
templates:
|
|
193
|
-
cursor-mdc: |
|
|
194
|
-
---
|
|
195
|
-
description: {{template_extra.description}}
|
|
196
|
-
globs: {{template_extra.globs}}
|
|
197
|
-
alwaysApply: {{template_extra.alwaysApply}}
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
{{render.generated_banner}}
|
|
201
|
-
|
|
202
|
-
{{render.body}}
|
|
203
|
-
markdown-plain: |
|
|
204
|
-
{{render.generated_banner}}
|
|
205
|
-
|
|
206
|
-
{{render.body}}
|
|
207
|
-
claude-import-stub: |
|
|
208
|
-
@agent/session-protocol.md
|
|
209
|
-
@agent.md
|
|
210
|
-
|
|
211
|
-
<!-- ADOPTER_C03_EXTENSIONS -->
|
|
212
|
-
|
|
213
|
-
# Per-project composition (seed / render-harness --project)
|
|
214
|
-
per_project:
|
|
215
|
-
compose_body: |
|
|
216
|
-
{{render.session_protocol_body}}
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
# Project entrypoint
|
|
221
|
-
|
|
222
|
-
@agent.md
|
|
223
|
-
note: |
|
|
224
|
-
For Cursor/Aider/etc., render-harness concatenates session-protocol + projects/PID/agent.md
|
|
225
|
-
into the generated install path. For Claude, per_project_template uses separate @imports.
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# Agent Session-Start Protocol — <ORG_NAME>
|
|
2
|
-
|
|
3
|
-
This is the **canonical** session-start protocol for any AI coding agent working in this workspace. It is delivered to each tool at its conventional path (`CLAUDE.md`, `.cursor/rules/agent.mdc`, `AGENTS.md`, `CONVENTIONS.md`, …) by `scripts/render-harness.sh`, driven by `agent/harness-manifest.yaml`. **Edit the protocol here, then re-render — never hand-edit the generated copies** (they carry a "do not edit" banner).
|
|
4
|
-
|
|
5
|
-
## 0. New session — agent speaks first (Pattern 1)
|
|
6
|
-
|
|
7
|
-
**Applies to:** every new Cursor Agent/Chat session, every new `claude` invocation, and every new conversation after `/clear`.
|
|
8
|
-
|
|
9
|
-
When this protocol is loaded, your **first assistant message** in the session must run the C01 checklist (§1–§2 below) and post a **context manifest** — **before** planning work, proposing tasks, or editing files.
|
|
10
|
-
|
|
11
|
-
| Trigger | What you do |
|
|
12
|
-
|---|---|
|
|
13
|
-
| User's first message is a greeting, "start", "go", "ready", or session opener | Run §1–§2, post manifest, **stop and wait** |
|
|
14
|
-
| User's first message already contains a **specific work task** | Still run §1–§2 first; post a **short** manifest, then address the task |
|
|
15
|
-
| No active project (framework/contrib mode; no `active` entry in `registry.yaml`) | Post manifest stating no active project; load org layer + `agent.md` only; wait for direction |
|
|
16
|
-
|
|
17
|
-
**Do not** wait for the user to paste the kickoff prompt from `DEVELOPER_GUIDE.md` — that template is for humans; you execute the same steps proactively.
|
|
18
|
-
|
|
19
|
-
### Context manifest (required format)
|
|
20
|
-
|
|
21
|
-
Use this structure in your first reply:
|
|
22
|
-
|
|
23
|
-
```markdown
|
|
24
|
-
## Context manifest
|
|
25
|
-
|
|
26
|
-
- **Project:** <PROJECT_ID or "none">
|
|
27
|
-
- **Branch:** <current git branch>
|
|
28
|
-
- **Status / assigned_to:** <from project.yaml, or n/a>
|
|
29
|
-
- **Repos:** <primary repos from project.yaml, or n/a>
|
|
30
|
-
- **Open todos:** <bullets from todo.md ## Open, or "none">
|
|
31
|
-
- **Layers loaded:** org ✓/✗ · project ✓/✗ · repo ✓/✗ · prefs ✓/✗
|
|
32
|
-
- **Awaiting:** your direction (no tasks proposed)
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
After the manifest, **stop**. Do not propose implementation work unless the user's first message already asked for something specific — and even then, complete the manifest first.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
Before you change any code, complete the steps below.
|
|
40
|
-
|
|
41
|
-
## 1. Read `org-config.yaml` first — every framework file references its values
|
|
42
|
-
|
|
43
|
-
Read `org-config.yaml` at the workspace repo root before anything else. The framework ships with no org-specific values baked in; instead, files refer to org values via angle-bracketed tokens that map to keys in `org-config.yaml`:
|
|
44
|
-
|
|
45
|
-
| Token | Key in `org-config.yaml` |
|
|
46
|
-
| --- | --- |
|
|
47
|
-
| `<ORG_NAME>` | `org_name` |
|
|
48
|
-
| `<ORG_SHORT_NAME>` | `org_short_name` |
|
|
49
|
-
| `<ORG_SLUG>` | `org_slug` |
|
|
50
|
-
| `<org_slug>` (lowercase) | `org_slug_lower` |
|
|
51
|
-
| `<ORG_REPO_URL>` | `org_repo_url` |
|
|
52
|
-
| `<GITHUB_ORG>` | `github_org` |
|
|
53
|
-
| `<WORKSPACE_REPO>` | `workspace_repo` |
|
|
54
|
-
| `<DEFAULT_BRANCH>` | `default_branch` |
|
|
55
|
-
| `<DEFAULT_CODE_BRANCH>` | `default_code_branch` |
|
|
56
|
-
| `<AGENT_WORK_ROOT>` | `agent_work_root` |
|
|
57
|
-
| `<POLICY_OWNER_EMAIL>` | `policy_owner_email` |
|
|
58
|
-
| `<POLICY_OWNER_GITHUB>` | `policy_owner_github` |
|
|
59
|
-
| `<LEGAL_OWNER_GITHUB>` etc. | `legal_owner_github`, `infra_owner_github`, `system_arch_owner_github`, `data_arch_owner_github` |
|
|
60
|
-
| `<POLICY_EFFECTIVE_DATE>` | `policy_effective_date` |
|
|
61
|
-
|
|
62
|
-
Tokens like `<PROJECT_ID>`, `<repo-name>`, `<your-gh-login>` are per-session values you'll discover from the current branch, `registry.yaml`, and `gh api user`.
|
|
63
|
-
|
|
64
|
-
If `org-config.yaml` has empty values (`org_name: ""`), the workspace is still in TEMPLATE state. Hard-stop and tell the human to run `./setup.sh`.
|
|
65
|
-
|
|
66
|
-
## 2. Load four knowledge layers — fresh every session
|
|
67
|
-
|
|
68
|
-
Read these in priority order (highest first). Never use cached layers from a prior session:
|
|
69
|
-
|
|
70
|
-
1. **Org-wide knowledge** — `knowledge/` in this repo, from the `<DEFAULT_BRANCH>` branch.
|
|
71
|
-
2. **Active project** — `projects/<PROJECT_ID>/knowledge/` plus the project's own entrypoint at `projects/<PROJECT_ID>/agent.md`. To determine the active `PROJECT_ID`: check `registry.yaml` for entries with `status: active`, and check the current git branch (project branches are named `brnch-NNN-<slug>`).
|
|
72
|
-
3. **Repo-local** — `<repo>/knowledge/` for each linked code repo at `$AGENT_WORK_ROOT/<PROJECT_ID>/<repo-name>/`.
|
|
73
|
-
4. **Your developer preferences** — `$AGENT_WORK_ROOT/preferences/<your-gh-login>.md`. Run `gh api user --jq .login` to determine your handle; load **only** your file. Other files in that directory belong to other developers — do not read them.
|
|
74
|
-
|
|
75
|
-
Higher layers always win. Developer preferences cannot override repo-local or org-wide knowledge.
|
|
76
|
-
|
|
77
|
-
## 3. Verify project state (C01 — hard stops)
|
|
78
|
-
|
|
79
|
-
If a project is active:
|
|
80
|
-
|
|
81
|
-
- Confirm you are authorized: you have **write access to the project's linked GitHub Project** (the authorization source of truth — an owner grants it via `./prj manage assign`). `assigned_to` in `project.yaml` is a display/audit cache, **not** the gate. When on a task sub-branch (`brnch-NNN-<slug>/<task-slug>`), confirm that sub-branch's assignee is you.
|
|
82
|
-
- `project.yaml`'s `status` must be `active`.
|
|
83
|
-
- Read `projects/<PROJECT_ID>/knowledge/todo.md` and surface its `## Open` items to the developer before planning new work.
|
|
84
|
-
|
|
85
|
-
If any of these can't be verified, hard-stop and surface to the human. Do not commit anything.
|
|
86
|
-
|
|
87
|
-
## 4. What's writable, what's not
|
|
88
|
-
|
|
89
|
-
During an active project:
|
|
90
|
-
|
|
91
|
-
- ✅ Writable: `projects/<PROJECT_ID>/` (workspace repo) and code on the project branch in cloned repos under `$AGENT_WORK_ROOT/<PROJECT_ID>/`.
|
|
92
|
-
- ❌ Read-only: `<WORKSPACE_REPO>/knowledge/` — never edit during an active project.
|
|
93
|
-
- ❌ Never hand-manage task state — tasks are GitHub Issues on the board (open = active, closed = done); create with `./prj task`, land with `./prj merge`.
|
|
94
|
-
- ❌ Don't create GitHub Issues unilaterally — those represent business intent that humans add to the GitHub Project board.
|
|
95
|
-
|
|
96
|
-
## 5. Where work happens
|
|
97
|
-
|
|
98
|
-
- Code repos are cloned at `$AGENT_WORK_ROOT/<PROJECT_ID>/<repo-name>/`, each on the project branch.
|
|
99
|
-
- Code changes go in those cloned repos — **NOT** in the workspace repo's tree.
|
|
100
|
-
- Project metadata (knowledge, decisions, to-dos) goes in `projects/<PROJECT_ID>/` in the workspace repo.
|
|
101
|
-
|
|
102
|
-
## 6. During work
|
|
103
|
-
|
|
104
|
-
- Capture decisions, exceptions, and policy notes in `projects/<PROJECT_ID>/knowledge/` as you make them — not at session end.
|
|
105
|
-
- **Draw, don't just describe.** When the knowledge you're capturing has a flow, architecture, sequence, state machine, or relationship, author it as a **Mermaid diagram (text, never an image — POL-414)** instead of prose. One artifact serves both readers: it renders as a picture for humans and stays ~tens of diffable, RAG-indexable lines for agents and PR review. Default to a diagram for anything structural; reach for `flowchart`/`sequenceDiagram`/`stateDiagram`/`erDiagram`/`C4Context` as fits.
|
|
106
|
-
- Capture intermediate to-dos in `projects/<PROJECT_ID>/knowledge/todo.md` under `## Open` as they arise.
|
|
107
|
-
- When an item from `todo.md` is resolved, move it to `## Done` with a short note (commit SHA, PR link, or one-line outcome).
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
For the canonical, full version of this protocol and the policy that governs it:
|
|
112
|
-
|
|
113
|
-
- **`docs/DEVELOPER_GUIDE.md`** — step-by-step session walkthrough with example prompts.
|
|
114
|
-
- **`knowledge/policies/agentic-development-policy.md`** — full policy text. POL-113 through POL-171 govern session protocol.
|
|
115
|
-
|
|
116
|
-
Per-project specifics (the actual `<PROJECT_ID>`, paths, GitHub Project URL, etc.) are filled in at `projects/<PROJECT_ID>/agent.md` once the project is seeded — that file is your project-specific entrypoint.
|