Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
329 changes: 159 additions & 170 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/public/mock-clan/spec/clan.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,4 @@ Agent provides a complete HTML document (preferred) or fragment. The `html` fiel

## Licence

CLAN Specification — Apache License 2.0
CLAN Specification — MPL-2.0
2 changes: 1 addition & 1 deletion crates/clan-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ println!("{}", ctx.prompt);

## License

Licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/saieeshward/clan/blob/main/LICENSE).
Licensed under the Mozilla Public License, Version 2.0. See [LICENSE](https://github.com/saieeshward/clan/blob/main/LICENSE).
57 changes: 57 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -euo pipefail

VERSION="1.1.5"
REPO="saieeshward/clan"
BIN_DIR="/usr/local/bin"
BIN_NAME="clan"

# Detect OS and arch
OS="$(uname -s)"
ARCH="$(uname -m)"

case "$OS" in
Darwin)
case "$ARCH" in
arm64) TARGET="aarch64-apple-darwin" ;;
x86_64) TARGET="x86_64-apple-darwin" ;;
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
esac
;;
Linux)
case "$ARCH" in
x86_64) TARGET="x86_64-unknown-linux-gnu" ;;
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
esac
;;
*)
echo "Unsupported OS: $OS"
echo "Windows users: download the .msi from https://github.com/$REPO/releases"
exit 1
;;
esac

TARBALL="clan-v${VERSION}-${TARGET}.tar.gz"
URL="https://github.com/${REPO}/releases/download/v${VERSION}/${TARBALL}"

echo "Installing clan v${VERSION} for ${TARGET}..."

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

curl -fsSL "$URL" -o "$TMP/$TARBALL"
tar -xzf "$TMP/$TARBALL" -C "$TMP"

# Install binary
if [ -w "$BIN_DIR" ]; then
install -m 755 "$TMP/clan" "$BIN_DIR/$BIN_NAME"
else
sudo install -m 755 "$TMP/clan" "$BIN_DIR/$BIN_NAME"
fi

# Clear macOS quarantine
if [ "$OS" = "Darwin" ]; then
xattr -d com.apple.quarantine "$BIN_DIR/$BIN_NAME" 2>/dev/null || true
fi

echo "clan $(clan --version) installed to $BIN_DIR/$BIN_NAME"
2 changes: 1 addition & 1 deletion spec/CLAN-SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Agent content (`agent/`) and human content (`human/`) are strictly separated. Ag
Every CLAN file carries its own specification (`spec/`). An agent that has never encountered CLAN before can understand the format and produce valid output from a single file.

### Openness
The format specification and reference SDK are open (Apache 2.0). No CLAN-compatible implementation requires a licence. The format does not depend on any proprietary system.
The format specification and reference SDK are open (MPL-2.0). No CLAN-compatible implementation requires a licence. The format does not depend on any proprietary system.

---

Expand Down
1 change: 1 addition & 0 deletions test-sandbox/happy/forkmerge/adhoc/summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"recommendation":"Build","budget_eur":520000,"top_risks":["opportunity cost","market timing"],"assumptions":"Build creates moat"}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
18 changes: 18 additions & 0 deletions test-sandbox/happy/forkmerge/receipts/receipt-analyst-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"agent": "analyst-a",
"namespace": "analyst_a",
"branch_file": "test-sandbox/happy/forkmerge/branches/analyst-a.clan",
"action": "cost-benefit analysis: recommends Build",
"fields_written": {
"analyst_a_recommendation": "Build",
"analyst_a_budget_eur": 450000,
"analyst_a_top_risks": [
"integration complexity",
"talent retention",
"timeline overrun"
],
"analyst_a_assumptions": "In-house team can deliver in 18 months; full API access to all partners"
},
"validation": "OK",
"timestamp": "2026-06-11T00:00:00Z"
}
14 changes: 14 additions & 0 deletions test-sandbox/happy/forkmerge/receipts/receipt-analyst-b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"agent": "analyst-b",
"namespace": "analyst_b",
"branch_file": "test-sandbox/happy/forkmerge/branches/analyst-b.clan",
"action": "procurement analysis: recommends Buy",
"fields_written": {
"analyst_b_recommendation": "Buy",
"analyst_b_budget_eur": 280000,
"analyst_b_top_risks": ["vendor lock-in", "customization limits", "data migration"],
"analyst_b_assumptions": "Off-the-shelf covers 90% of requirements; 6-month implementation"
},
"validation": "OK",
"timestamp": "2026-06-11"
}
14 changes: 14 additions & 0 deletions test-sandbox/happy/forkmerge/receipts/receipt-analyst-c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"agent": "analyst-c",
"namespace": "analyst_c",
"branch_file": "test-sandbox/happy/forkmerge/branches/analyst-c.clan",
"action": "risk analysis: recommends Buy",
"fields_written": {
"analyst_c_recommendation": "Buy",
"analyst_c_budget_eur": 310000,
"analyst_c_top_risks": ["scope creep", "resource contention", "regulatory compliance gaps"],
"analyst_c_assumptions": "Vendor solution achieves GDPR compliance out-of-box; EU data residency available"
},
"validation": "OK",
"timestamp": "2026-06-11T00:00:00Z"
}
14 changes: 14 additions & 0 deletions test-sandbox/happy/forkmerge/receipts/receipt-analyst-d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"agent": "analyst-d",
"namespace": "analyst_d",
"branch_file": "test-sandbox/happy/forkmerge/branches/analyst-d.clan",
"action": "strategic analysis: recommends Build",
"validation": "OK",
"fields_written": {
"analyst_d_recommendation": "Build",
"analyst_d_budget_eur": 520000,
"analyst_d_top_risks": ["opportunity cost", "market timing", "technical debt accumulation"],
"analyst_d_assumptions": "Build path creates competitive moat; 24-month full delivery"
},
"timestamp": "2026-06-11T00:00:00Z"
}
25 changes: 25 additions & 0 deletions test-sandbox/happy/forkmerge/receipts/receipt-synthesizer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"agent": "synthesizer",
"timestamp": "2026-06-11T22:26:00.000Z",
"merge": {
"branches": [
"test-sandbox/happy/forkmerge/branches/analyst-a.clan",
"test-sandbox/happy/forkmerge/branches/analyst-b.clan",
"test-sandbox/happy/forkmerge/branches/analyst-c.clan",
"test-sandbox/happy/forkmerge/branches/analyst-d.clan"
],
"output": "test-sandbox/happy/forkmerge/work/merged.clan",
"contested_keys": 0
},
"adjudication": {
"final_recommendation": "Buy",
"final_budget_eur": 295000,
"final_rationale": "2 of 4 analysts recommend Buy; weighted average budget EUR 295k; vendor GDPR compliance reduces risk profile",
"votes": {
"Buy": ["analyst-b", "analyst-c"],
"Build": ["analyst-a", "analyst-d"]
}
},
"validation": "OK",
"final_output": "test-sandbox/happy/forkmerge/work/final.clan"
}
Binary file added test-sandbox/happy/forkmerge/work/final.clan
Binary file not shown.
Binary file added test-sandbox/happy/forkmerge/work/merged.clan
Binary file not shown.
Binary file added test-sandbox/happy/forkmerge/work/seed.clan
Binary file not shown.
Binary file modified test-sandbox/happy/forkmerge2/branches/analyst-a.clan
Binary file not shown.
Binary file modified test-sandbox/happy/forkmerge2/branches/analyst-b.clan
Binary file not shown.
Binary file modified test-sandbox/happy/forkmerge2/branches/analyst-c.clan
Binary file not shown.
Binary file modified test-sandbox/happy/forkmerge2/branches/analyst-d.clan
Binary file not shown.
1 change: 1 addition & 0 deletions test-sandbox/happy/forkmerge2/ctxdir/analyst-a.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You are analyst-a. Your assessment: BUILD. Write recommendation=Build, budget_eur=450000, top_risks=[integration complexity, talent retention, timeline overrun], assumptions=In-house team can deliver in 18 months.
1 change: 1 addition & 0 deletions test-sandbox/happy/forkmerge2/ctxdir/analyst-b.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You are analyst-b. Your assessment: BUY. Write recommendation=Buy, budget_eur=280000, top_risks=[vendor lock-in, customization limits, data migration], assumptions=Off-the-shelf covers 90% of requirements in 6 months.
1 change: 1 addition & 0 deletions test-sandbox/happy/forkmerge2/ctxdir/analyst-c.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You are analyst-c. Your assessment: BUY. Write recommendation=Buy, budget_eur=310000, top_risks=[scope creep, resource contention, regulatory compliance gaps], assumptions=Vendor achieves GDPR compliance; EU data residency available.
1 change: 1 addition & 0 deletions test-sandbox/happy/forkmerge2/ctxdir/analyst-d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You are analyst-d. Your assessment: BUILD. Write recommendation=Build, budget_eur=520000, top_risks=[opportunity cost, market timing, technical debt], assumptions=Build creates competitive moat; 24-month full delivery.
16 changes: 0 additions & 16 deletions test-sandbox/happy/forkmerge2/receipts/receipt-a.json

This file was deleted.

26 changes: 26 additions & 0 deletions test-sandbox/happy/forkmerge2/receipts/receipt-analyst-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"role": "analyst-a",
"commands_run": [
"clan read context test-sandbox/happy/forkmerge2/branches/analyst-a.clan",
"clan read --help",
"clan agent-help",
"clan read agent test-sandbox/happy/forkmerge2/branches/analyst-a.clan",
"clan patch-data test-sandbox/happy/forkmerge2/branches/analyst-a.clan /tmp/analyst-a.json --namespace --agent analyst-a --action \"wrote build-vs-buy assessment\"",
"clan validate test-sandbox/happy/forkmerge2/branches/analyst-a.clan"
],
"files_read": [
{ "file": "test-sandbox/happy/forkmerge2/branches/analyst-a.clan (read agent)", "approx_chars": 11000 },
{ "file": "/tmp/analyst-a.json", "approx_chars": 180 }
],
"files_written": [
{ "file": "/tmp/analyst-a.json", "chars": 167 },
{ "file": "test-sandbox/happy/forkmerge2/receipts/receipt-analyst-a.json", "chars": 1100 }
],
"output_chars": 167,
"errors": [
{ "what": "clan read context -> unrecognized subcommand 'context'", "recovered_by": "ran clan read --help, used 'clan read agent' instead" },
{ "what": "/tmp/analyst-a.json pre-existed with a longer assumptions value not matching context", "recovered_by": "read it, overwrote with exact context values (assumptions='In-house team can deliver in 18 months.')" }
],
"problems_and_friction": "Task said 'clan read context' but the actual subcommand is 'clan read agent'. A stale /tmp/analyst-a.json existed with mismatched assumptions text; overwrote to match the EXACT context value. Write tool also required reading the pre-existing file first.",
"context_understood": "Branch agent analyst-a in a fork/merge scenario. Must write four build-vs-buy findings only into my own namespace (agents/analyst-a/) via patch-data --namespace since shared data is locked until merge. Recommendation=Build, budget_eur=450000, three risks, assumptions string, matching output-schema exactly."
}
23 changes: 23 additions & 0 deletions test-sandbox/happy/forkmerge2/receipts/receipt-analyst-b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"role": "analyst-b",
"commands_run": [
"clan read --help",
"clan agent-help",
"clan read agent test-sandbox/happy/forkmerge2/branches/analyst-b.clan",
"clan patch-data test-sandbox/happy/forkmerge2/branches/analyst-b.clan /tmp/analyst-b.json --namespace --agent analyst-b --action \"wrote build-vs-buy assessment\"",
"clan validate test-sandbox/happy/forkmerge2/branches/analyst-b.clan"
],
"files_read": [
{ "file": "test-sandbox/happy/forkmerge2/branches/analyst-b.clan (read agent context)", "approx_chars": 9800 }
],
"files_written": [
{ "file": "/tmp/analyst-b.json", "chars": 210 },
{ "file": "test-sandbox/happy/forkmerge2/branches/analyst-b.clan", "chars": 210 }
],
"output_chars": 210,
"errors": [
{ "what": "clan read context -> unrecognized subcommand 'context'", "recovered_by": "used 'clan read agent' which is the correct subcommand per --help" }
],
"problems_and_friction": "Task said 'clan read context' but the actual subcommand is 'clan read agent'. The agent guide warns that prose fields like 'assumptions' may be contested at merge since a sibling may write the same key; task instructed exact key 'assumptions' so I followed task values verbatim.",
"context_understood": "Branch agent analyst-b in a fork; wrote build-vs-buy assessment (Buy, 280000 EUR, 3 risks, off-the-shelf assumption) into my namespace via --namespace patch-data. Writes to shared/ are blocked until merge."
}
26 changes: 26 additions & 0 deletions test-sandbox/happy/forkmerge2/receipts/receipt-analyst-c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"role": "analyst-c",
"commands_run": [
"clan read context (failed: invalid subcommand)",
"clan read --help",
"clan agent-help",
"clan read agent test-sandbox/happy/forkmerge2/branches/analyst-c.clan",
"clan patch-data test-sandbox/happy/forkmerge2/branches/analyst-c.clan /tmp/analyst-c.json --namespace --agent analyst-c --action \"wrote build-vs-buy assessment\"",
"clan validate test-sandbox/happy/forkmerge2/branches/analyst-c.clan"
],
"files_read": [
{ "file": "test-sandbox/happy/forkmerge2/branches/analyst-c.clan (agent context)", "approx_chars": 9500 },
{ "file": "/tmp/analyst-c.json", "approx_chars": 190 }
],
"files_written": [
{ "file": "/tmp/analyst-c.json", "chars": 191 },
{ "file": "test-sandbox/happy/forkmerge2/receipts/receipt-analyst-c.json", "chars": 1100 }
],
"output_chars": 191,
"errors": [
{ "what": "`clan read context` rejected (no such subcommand)", "recovered_by": "ran `clan read --help`, used `clan read agent` instead" },
{ "what": "/tmp/analyst-c.json existed with a stale `assumptions` value (out-of-box wording, missing period)", "recovered_by": "read it, then overwrote with exact task values" }
],
"problems_and_friction": "Task instruction said `clan read context` but the actual subcommand is `clan read agent`. Pre-existing /tmp/analyst-c.json had drifted text. Resolved both quickly.",
"context_understood": "Branch agent analyst-c, BUY assessment. Wrote four keys (recommendation=Buy, budget_eur=310000, top_risks 3-item array, assumptions string) into own namespace via patch-data --namespace; shared/human writes locked until merge. Aware assumptions key may be flagged contested at merge if a sibling also writes it."
}
25 changes: 25 additions & 0 deletions test-sandbox/happy/forkmerge2/receipts/receipt-analyst-d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"role": "analyst-d",
"commands_run": [
"clan read agent test-sandbox/happy/forkmerge2/branches/analyst-d.clan",
"clan read --help",
"clan agent-help",
"clan patch-data test-sandbox/happy/forkmerge2/branches/analyst-d.clan /tmp/analyst-d.json --namespace --agent analyst-d --action \"wrote build-vs-buy assessment\"",
"clan validate test-sandbox/happy/forkmerge2/branches/analyst-d.clan"
],
"files_read": [
{ "file": "test-sandbox/happy/forkmerge2/branches/analyst-d.clan", "approx_chars": 11000 },
{ "file": "/tmp/analyst-d.json", "approx_chars": 180 }
],
"files_written": [
{ "file": "/tmp/analyst-d.json", "chars": 168 },
{ "file": "test-sandbox/happy/forkmerge2/receipts/receipt-analyst-d.json", "chars": 900 }
],
"output_chars": 168,
"errors": [
{ "what": "clan read context (invalid subcommand 'context')", "recovered_by": "checked clan read --help; correct subcommand is 'clan read agent'" },
{ "what": "/tmp/analyst-d.json pre-existed with slightly different values (technical debt accumulation, 24-month full delivery window)", "recovered_by": "overwrote with exact context values via Write after reading it" }
],
"problems_and_friction": "Task said 'clan read context' but the actual subcommand is 'clan read agent'. A stale /tmp/analyst-d.json existed with near-but-not-exact values; corrected to match context exactly.",
"context_understood": "Branch agent analyst-d in fork/merge. Recommendation=Build, budget_eur=520000, top_risks=[opportunity cost, market timing, technical debt], assumptions=Build creates competitive moat; 24-month full delivery. Wrote to own namespace with --namespace; shared/ writes locked until merge."
}
1 change: 0 additions & 1 deletion test-sandbox/happy/forkmerge2/receipts/receipt-b.json

This file was deleted.

16 changes: 0 additions & 16 deletions test-sandbox/happy/forkmerge2/receipts/receipt-c.json

This file was deleted.

17 changes: 0 additions & 17 deletions test-sandbox/happy/forkmerge2/receipts/receipt-d.json

This file was deleted.

Binary file modified test-sandbox/happy/forkmerge2/work/merged.clan
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2026-06-11 hop-01 pricing-update: zoho_price_per_seat 45→38, zoho_annual_total 21600→18240 (38×40×12); report.html cost table updated to match.
2026-06-12 | analyst | Zoho CRM repriced to $38/seat; annual total updated to $18240 in data.json and report.html cost table
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hop02 risk-add: appended Vendor lock-in risk (Medium) to data.json risks[] and spliced supplied row into report.html #risk-rows (already present; idempotent).
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2026-06-11 hop-02 risk-add: appended risk "Vendor lock-in" severity Medium mitigation "Quarterly data-export clause in contract" to risks[] in data.json and added matching <tr> to risk table in report.html.
2026-06-12 | analyst | added Vendor lock-in risk (Medium) with quarterly data-export mitigation to data.json risks[] and report.html risk table
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"risk":"Vendor lock-in","severity":"Medium","mitigation":"Quarterly data-export clause in contract"}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
{"risk": "Vendor lock-in", "severity": "Medium", "mitigation": "Quarterly data-export clause in contract"}
{"risk": "Integration latency on NetSuite sync", "severity": "Medium", "mitigation": "Nightly batch fallback"},
{"risk":"Vendor lock-in","severity":"Medium","mitigation":"Quarterly data-export clause in contract"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2026-06-11 hop-03 date-update: rollout_phase2_date 2026-08-012026-09-15 in data.json; id=phase2 cell updated in report.html.
2026-06-12 | date-update | rollout_phase2_date 2026-08-01 -> 2026-09-15 in data.json and report.html (id="phase2"); both already at target (idempotent)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<td id="phase2">2026-09-15</td>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2026-06-12 | summary-rewrite | replaced exec_summary in data.json and report.html (id="exec-summary") with supplied Zoho-leading text per h1-supplied/exec-summary.txt; both already at target (idempotent)
Loading
Loading