docs: add universal context capsule
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
# JKTV AI Working Agreement
|
||||||
|
|
||||||
|
Read `context/boot.md` and `context/capsule.json` before changing the product.
|
||||||
|
Then read the smallest relevant document and implementation module.
|
||||||
|
|
||||||
|
## Source Boundaries
|
||||||
|
|
||||||
|
- JKTV owns the CS2 team data model, import pipeline, player and match views,
|
||||||
|
roster analysis and self-hosted application source.
|
||||||
|
- JOps owns shared edge, deployment observation and platform authentication
|
||||||
|
facts.
|
||||||
|
- Imported match files, runtime databases, tokens and user content remain
|
||||||
|
outside Git.
|
||||||
|
|
||||||
|
## Change Protocol
|
||||||
|
|
||||||
|
1. Preserve L1 raw, L2 normalized and L3 product-data boundaries.
|
||||||
|
2. Keep derived statistics reproducible from source match data.
|
||||||
|
3. Reject write operations without server-side authorization and CSRF checks.
|
||||||
|
4. Update product or data architecture documentation with contract changes.
|
||||||
|
5. Run `make context-check` and `make check` before committing.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
PYTHON := .venv/bin/python
|
PYTHON := .venv/bin/python
|
||||||
|
|
||||||
.PHONY: install bootstrap run test check l1 l2 l3 l3-all pipeline prepare-data docker-up docker-down docker-logs
|
.PHONY: install bootstrap run test check context-check l1 l2 l3 l3-all pipeline prepare-data docker-up docker-down docker-logs
|
||||||
|
|
||||||
install:
|
install:
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@@ -15,7 +15,10 @@ run:
|
|||||||
test:
|
test:
|
||||||
$(PYTHON) -m unittest discover -v
|
$(PYTHON) -m unittest discover -v
|
||||||
|
|
||||||
check:
|
context-check:
|
||||||
|
python3 utils/check_context.py
|
||||||
|
|
||||||
|
check: context-check
|
||||||
$(PYTHON) -m compileall -q web database tests wsgi.py
|
$(PYTHON) -m compileall -q web database tests wsgi.py
|
||||||
$(PYTHON) -m unittest discover -v
|
$(PYTHON) -m unittest discover -v
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# JKTV Context Boot
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
JKTV is a private CS2 team data product. It turns imported match captures into
|
||||||
|
auditable player, match, roster, opponent, award and tactical views.
|
||||||
|
|
||||||
|
## Repository Map
|
||||||
|
|
||||||
|
```text
|
||||||
|
database/L1/ raw capture processing
|
||||||
|
database/L2/ normalized match facts
|
||||||
|
database/L3/ player and team product models
|
||||||
|
web/ Flask application, routes, services and templates
|
||||||
|
tests/ pipeline and application checks
|
||||||
|
docs/ product and data architecture
|
||||||
|
context/ bounded repository identity for Universal Context
|
||||||
|
```
|
||||||
|
|
||||||
|
## Read Order
|
||||||
|
|
||||||
|
```text
|
||||||
|
AGENTS.md
|
||||||
|
-> context/boot.md
|
||||||
|
-> context/capsule.json
|
||||||
|
-> README.md
|
||||||
|
-> docs/FeatureRDD.md
|
||||||
|
-> relevant pipeline or web module
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime match captures, databases, tokens and user content are not context
|
||||||
|
inputs. Current production claims require a fresh JOps observation.
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"schema": 1,
|
||||||
|
"kind": "jcm.repository-capsule",
|
||||||
|
"repository": {
|
||||||
|
"id": "jktv",
|
||||||
|
"name": "JKTV",
|
||||||
|
"remote": "Jacky/JKTV-online",
|
||||||
|
"role": "private-team-data-product",
|
||||||
|
"summary": "Owns the self-hosted CS2 team data pipeline, player and match pages, roster analytics, awards and tactical tools."
|
||||||
|
},
|
||||||
|
"domains": [
|
||||||
|
"platform"
|
||||||
|
],
|
||||||
|
"context": {
|
||||||
|
"entrypoint": "AGENTS.md",
|
||||||
|
"read_order": [
|
||||||
|
"AGENTS.md",
|
||||||
|
"context/boot.md",
|
||||||
|
"context/capsule.json",
|
||||||
|
"context/manifest.json",
|
||||||
|
"README.md",
|
||||||
|
"docs/FeatureRDD.md",
|
||||||
|
"docs/三层数据库架构重构计划_902db62c.md"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"owns": [
|
||||||
|
"CS2 match import and L1 to L3 data pipeline",
|
||||||
|
"Player, match, roster, opponent and tactical product views",
|
||||||
|
"Derived statistics, awards and data integrity checks"
|
||||||
|
],
|
||||||
|
"excludes": [
|
||||||
|
"Shared platform edge and production operations",
|
||||||
|
"Raw private match captures and runtime databases",
|
||||||
|
"Authentication tokens and user content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"contracts": null,
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"id": "jktv-web",
|
||||||
|
"name": "JKTV",
|
||||||
|
"kind": "team-data-application",
|
||||||
|
"summary": "Self-hosted CS2 team history, comparison, roster and tactical application.",
|
||||||
|
"public_urls": [
|
||||||
|
"https://tv.jacky0987.xyz/"
|
||||||
|
],
|
||||||
|
"domains": [
|
||||||
|
"platform"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relationships": [
|
||||||
|
{
|
||||||
|
"target": "jops",
|
||||||
|
"type": "operates",
|
||||||
|
"summary": "Relies on JOps for shared edge and production runtime evidence."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"runtime": {
|
||||||
|
"authority": "none"
|
||||||
|
},
|
||||||
|
"current_state": {
|
||||||
|
"status": "released",
|
||||||
|
"summary": "The repository baseline is the 2.0.0 Beta self-hosted product; source documentation does not claim current production health.",
|
||||||
|
"evidence": [
|
||||||
|
"README.md",
|
||||||
|
"docs/FeatureRDD.md",
|
||||||
|
"docs/三层数据库架构重构计划_902db62c.md"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"facts": [
|
||||||
|
{
|
||||||
|
"id": "jktv-product-boundary",
|
||||||
|
"scope": "platform",
|
||||||
|
"summary": "JKTV is an independently deployed CS2 team data product with a reproducible L1, L2 and L3 data pipeline.",
|
||||||
|
"authority": "canonical",
|
||||||
|
"evidence": "README.md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "2.0.0",
|
||||||
|
"bundle_type": "repo-local-ai",
|
||||||
|
"repository": {
|
||||||
|
"owner": "Jacky",
|
||||||
|
"name": "JKTV-online",
|
||||||
|
"role": "private-team-data-product"
|
||||||
|
},
|
||||||
|
"state": "RELEASED",
|
||||||
|
"runtime_state": "UNVERIFIED",
|
||||||
|
"entrypoint": "AGENTS.md",
|
||||||
|
"read_order": [
|
||||||
|
"AGENTS.md",
|
||||||
|
"context/boot.md",
|
||||||
|
"context/capsule.json",
|
||||||
|
"context/manifest.json",
|
||||||
|
"README.md",
|
||||||
|
"docs/FeatureRDD.md",
|
||||||
|
"docs/三层数据库架构重构计划_902db62c.md"
|
||||||
|
],
|
||||||
|
"contracts": {},
|
||||||
|
"dependencies": {
|
||||||
|
"strategy": "none"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"freshness": "requires_jops_observation"
|
||||||
|
},
|
||||||
|
"artifacts": [
|
||||||
|
"context/boot.md",
|
||||||
|
"context/capsule.json",
|
||||||
|
"README.md",
|
||||||
|
"docs/FeatureRDD.md",
|
||||||
|
"docs/三层数据库架构重构计划_902db62c.md"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
CAPSULE_FILE = ROOT / "context" / "capsule.json"
|
||||||
|
MANIFEST_FILE = ROOT / "context" / "manifest.json"
|
||||||
|
|
||||||
|
|
||||||
|
def fail(message):
|
||||||
|
raise SystemExit(f"context_check_error={message}")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
capsule = json.loads(CAPSULE_FILE.read_text(encoding="utf-8"))
|
||||||
|
manifest = json.loads(MANIFEST_FILE.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, json.JSONDecodeError) as error:
|
||||||
|
fail(f"invalid_capsule:{error}")
|
||||||
|
|
||||||
|
if (
|
||||||
|
capsule.get("schema") != 1
|
||||||
|
or capsule.get("kind") != "jcm.repository-capsule"
|
||||||
|
or capsule.get("repository", {}).get("id") != "jktv"
|
||||||
|
or capsule.get("repository", {}).get("remote") != "Jacky/JKTV-online"
|
||||||
|
):
|
||||||
|
fail("invalid_identity")
|
||||||
|
if (
|
||||||
|
manifest.get("schema_version") != "2.0.0"
|
||||||
|
or manifest.get("repository", {}).get("name") != "JKTV-online"
|
||||||
|
or "context/capsule.json" not in manifest.get("read_order", [])
|
||||||
|
):
|
||||||
|
fail("invalid_manifest")
|
||||||
|
|
||||||
|
paths = [
|
||||||
|
capsule.get("context", {}).get("entrypoint"),
|
||||||
|
*capsule.get("context", {}).get("read_order", []),
|
||||||
|
*capsule.get("current_state", {}).get("evidence", []),
|
||||||
|
*[fact.get("evidence") for fact in capsule.get("facts", [])],
|
||||||
|
]
|
||||||
|
for relative in paths:
|
||||||
|
if not relative or Path(relative).is_absolute() or ".." in Path(relative).parts:
|
||||||
|
fail(f"unsafe_path:{relative}")
|
||||||
|
if not (ROOT / relative).is_file():
|
||||||
|
fail(f"missing_path:{relative}")
|
||||||
|
|
||||||
|
print("context_check=ok")
|
||||||
Reference in New Issue
Block a user