Skip to content

Commit 9ac292c

Browse files
committed
완료: 시각 자산 출처 계약을 고정하고 manifest TODO 삭제
상황: 06 Visual Assets의 manifest pipeline은 24개 자산이 자체 제작·캡처로 정리돼 있었지만 생성 raster 8개의 promptHash가 원본 prompt 경로와 연결되지 않았고, 자체 소유 자산과 외부 라이선스 자산의 URL 규칙도 검증기가 구분하지 않아 TODO 삭제 조건이 남아 있었다. 변경: VisualAssetManifest provenance에 promptPath를 추가하고 buildVisualAssets.py가 prompt source root와 실제 SHA-256을 대조하도록 했다. proprietary-project는 licenseUrl null만 허용하고 licensedMedia는 구체 라이선스와 HTTPS 근거를 요구하도록 부정 회귀를 추가했다. 24개 원본을 전수 검수하고 생성 manifest와 Landing·Editor mirror를 동기화했으며 00-manifest-pipeline TODO와 parent 링크를 삭제하고 R10 draft scope를 다시 생성했다. 영향: 기존 24개 자산의 픽셀과 공개 경로는 바뀌지 않는다. 생성 raster 8개는 추적 가능한 prompt 원본을 가지며 출처 근거가 없는 외부 media는 manifest 단계에서 차단된다. 06 Visual Assets에는 instructional, Run capture, Local capture 세 packet만 남는다. 검증: uv run python -X utf8 tests/run.py gate visual-assets 통과. uv run python -X utf8 tests/run.py gate plan-quality 통과. uv run python -X utf8 -m pytest tests/plan/testMainPlanTodoPolicy.py -q --tb=short -p no:cacheprovider 6 passed. uv run python -X utf8 tests/run.py preflight 3/3 통과. 원본 24개 시각 검수, generatedRaster 8개 prompt hash 일치, licensedMedia 0개, proprietary-project 24개를 확인했다. git diff --cached --check 통과.
1 parent 96f95a4 commit 9ac292c

13 files changed

Lines changed: 176 additions & 95 deletions

File tree

assets/brand/tools/buildVisualAssets.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
ROOT = Path(__file__).resolve().parents[3]
1414
VISUAL_ROOT = ROOT / "assets" / "brand" / "visuals"
15+
PROMPTS_ROOT = VISUAL_ROOT / "prompts"
1516
MANIFEST_PATH = VISUAL_ROOT / "manifest.json"
1617
SCHEMA_PATH = VISUAL_ROOT / "manifest.schema.json"
1718
GENERATED_ROOT = VISUAL_ROOT / "generated"
@@ -147,8 +148,36 @@ def validateVisualManifest(manifest: dict[str, Any]) -> None:
147148
provenance = requiredObject(asset, "provenance", assetId)
148149
for field in ("author", "license", "fixtureId"):
149150
requiredText(provenance, field, f"{assetId}.provenance")
150-
if sourceType == "generatedRaster" and not provenance.get("promptHash"):
151-
raise VisualAssetError(f"{assetId}: generatedRaster requires promptHash")
151+
licenseName = provenance["license"]
152+
licenseUrl = provenance.get("licenseUrl")
153+
if licenseName == "proprietary-project" and licenseUrl is not None:
154+
raise VisualAssetError(f"{assetId}: proprietary-project licenseUrl must be null")
155+
if sourceType == "licensedMedia":
156+
if licenseName == "proprietary-project":
157+
raise VisualAssetError(f"{assetId}: licensedMedia cannot use proprietary-project")
158+
if not isinstance(licenseUrl, str) or not licenseUrl.startswith("https://"):
159+
raise VisualAssetError(f"{assetId}: licensedMedia requires an HTTPS licenseUrl")
160+
if sourceType == "generatedRaster":
161+
promptRelative = requiredText(
162+
provenance,
163+
"promptPath",
164+
f"{assetId}.provenance",
165+
)
166+
promptPath = resolvePromptPath(promptRelative)
167+
if not promptPath.is_file():
168+
raise VisualAssetError(f"{assetId}: missing prompt source {promptRelative}")
169+
promptHash = requiredText(
170+
provenance,
171+
"promptHash",
172+
f"{assetId}.provenance",
173+
)
174+
actualPromptHash = f"sha256-{sha256Bytes(promptPath.read_bytes())}"
175+
if promptHash != actualPromptHash:
176+
raise VisualAssetError(f"{assetId}: prompt hash drift")
177+
elif provenance.get("promptPath") is not None or provenance.get("promptHash") is not None:
178+
raise VisualAssetError(
179+
f"{assetId}: prompt provenance is limited to generatedRaster"
180+
)
152181

153182
rendering = requiredObject(asset, "rendering", assetId)
154183
width = requiredPositiveInt(rendering, "width", f"{assetId}.rendering")
@@ -401,6 +430,16 @@ def resolveSourcePath(relativeValue: str) -> Path:
401430
return resolved
402431

403432

433+
def resolvePromptPath(relativeValue: str) -> Path:
434+
relativePath = Path(relativeValue)
435+
if relativePath.is_absolute():
436+
raise VisualAssetError(f"visual prompt must be repository-relative: {relativeValue}")
437+
resolved = (ROOT / relativePath).resolve()
438+
if not resolved.is_relative_to(PROMPTS_ROOT.resolve()):
439+
raise VisualAssetError(f"visual prompt escapes prompt source root: {relativeValue}")
440+
return resolved
441+
442+
404443
def resolveCaptureSourcePath(relativeValue: str) -> Path:
405444
relativePath = Path(relativeValue)
406445
if relativePath.is_absolute():

assets/brand/visuals/generated/manifest.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schemaVersion": 1,
3-
"sourceManifestHash": "sha256-c4242eb050f0977c3335a34c406a5ee9a28f91897a7f9bc6ecf77e7bad0bb90e",
3+
"sourceManifestHash": "sha256-4735270950f5d042bb6099145d0336d7a100d1a84383fb7ec0bae00d77dfeac5",
44
"assets": [
55
{
66
"id": "runLearningDetail",
@@ -2060,6 +2060,7 @@
20602060
"license": "proprietary-project",
20612061
"licenseUrl": null,
20622062
"fixtureId": "python-fundamentals-domain-v1",
2063+
"promptPath": "assets/brand/visuals/prompts/python-fundamentals-v1.txt",
20632064
"promptHash": "sha256-45246801d7843b7af2cc0174e818e81a9d9e0d1925a4e7b738222dce3e4e5d38",
20642065
"lessonContentHash": null
20652066
},
@@ -2186,6 +2187,7 @@
21862187
"license": "proprietary-project",
21872188
"licenseUrl": null,
21882189
"fixtureId": "data-analysis-domain-v1",
2190+
"promptPath": "assets/brand/visuals/prompts/data-analysis-v1.txt",
21892191
"promptHash": "sha256-c737f07e956cf2e3c97cdec7ff696187f3585c3d665865623c2873a344bba484",
21902192
"lessonContentHash": null
21912193
},
@@ -2309,6 +2311,7 @@
23092311
"license": "proprietary-project",
23102312
"licenseUrl": null,
23112313
"fixtureId": "data-visualization-domain-v1",
2314+
"promptPath": "assets/brand/visuals/prompts/data-visualization-v1.txt",
23122315
"promptHash": "sha256-e850f31ca2c0d2bb88f54fe8d763a0bdeec70ed29732a5d466f8746a04ed35f1",
23132316
"lessonContentHash": null
23142317
},
@@ -2432,6 +2435,7 @@
24322435
"license": "proprietary-project",
24332436
"licenseUrl": null,
24342437
"fixtureId": "statistics-machine-learning-domain-v1",
2438+
"promptPath": "assets/brand/visuals/prompts/statistics-ml-v1.txt",
24352439
"promptHash": "sha256-882f948c62f95971f176cc50ee33b87daead4134ea0bcd2130c9bcba9ac4d0a5",
24362440
"lessonContentHash": null
24372441
},
@@ -2555,6 +2559,7 @@
25552559
"license": "proprietary-project",
25562560
"licenseUrl": null,
25572561
"fixtureId": "image-vision-domain-v1",
2562+
"promptPath": "assets/brand/visuals/prompts/image-vision-v1.txt",
25582563
"promptHash": "sha256-73fc05ae505bab09936dba44d712c45d882f7bafe4b9634a5b0bdb4055abd3ab",
25592564
"lessonContentHash": null
25602565
},
@@ -2678,6 +2683,7 @@
26782683
"license": "proprietary-project",
26792684
"licenseUrl": null,
26802685
"fixtureId": "learning-automation-domain-v1",
2686+
"promptPath": "assets/brand/visuals/prompts/automation-v1.txt",
26812687
"promptHash": "sha256-2f378e592935ce87e9eed1ae357053602f5e9a625cf8a656d28f5dbff71165b7",
26822688
"lessonContentHash": null
26832689
},
@@ -2801,6 +2807,7 @@
28012807
"license": "proprietary-project",
28022808
"licenseUrl": null,
28032809
"fixtureId": "developer-literacy-domain-v1",
2810+
"promptPath": "assets/brand/visuals/prompts/developer-literacy-v1.txt",
28042811
"promptHash": "sha256-85e38fd1ca4b81e80c950874eb38b7ad64a9fe79549dc36514be63d4bed709aa",
28052812
"lessonContentHash": null
28062813
},
@@ -2924,6 +2931,7 @@
29242931
"license": "proprietary-project",
29252932
"licenseUrl": null,
29262933
"fixtureId": "ai-integration-domain-v1",
2934+
"promptPath": "assets/brand/visuals/prompts/ai-integration-v1.txt",
29272935
"promptHash": "sha256-51f558f4635cfe113f30a3771b3d16437bd96f712cb726b65347c3f0e32c7479",
29282936
"lessonContentHash": null
29292937
},

assets/brand/visuals/manifest.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,7 @@
13551355
"license": "proprietary-project",
13561356
"licenseUrl": null,
13571357
"fixtureId": "python-fundamentals-domain-v1",
1358+
"promptPath": "assets/brand/visuals/prompts/python-fundamentals-v1.txt",
13581359
"promptHash": "sha256-45246801d7843b7af2cc0174e818e81a9d9e0d1925a4e7b738222dce3e4e5d38",
13591360
"lessonContentHash": null
13601361
},
@@ -1415,6 +1416,7 @@
14151416
"license": "proprietary-project",
14161417
"licenseUrl": null,
14171418
"fixtureId": "data-analysis-domain-v1",
1419+
"promptPath": "assets/brand/visuals/prompts/data-analysis-v1.txt",
14181420
"promptHash": "sha256-c737f07e956cf2e3c97cdec7ff696187f3585c3d665865623c2873a344bba484",
14191421
"lessonContentHash": null
14201422
},
@@ -1472,6 +1474,7 @@
14721474
"license": "proprietary-project",
14731475
"licenseUrl": null,
14741476
"fixtureId": "data-visualization-domain-v1",
1477+
"promptPath": "assets/brand/visuals/prompts/data-visualization-v1.txt",
14751478
"promptHash": "sha256-e850f31ca2c0d2bb88f54fe8d763a0bdeec70ed29732a5d466f8746a04ed35f1",
14761479
"lessonContentHash": null
14771480
},
@@ -1529,6 +1532,7 @@
15291532
"license": "proprietary-project",
15301533
"licenseUrl": null,
15311534
"fixtureId": "statistics-machine-learning-domain-v1",
1535+
"promptPath": "assets/brand/visuals/prompts/statistics-ml-v1.txt",
15321536
"promptHash": "sha256-882f948c62f95971f176cc50ee33b87daead4134ea0bcd2130c9bcba9ac4d0a5",
15331537
"lessonContentHash": null
15341538
},
@@ -1586,6 +1590,7 @@
15861590
"license": "proprietary-project",
15871591
"licenseUrl": null,
15881592
"fixtureId": "image-vision-domain-v1",
1593+
"promptPath": "assets/brand/visuals/prompts/image-vision-v1.txt",
15891594
"promptHash": "sha256-73fc05ae505bab09936dba44d712c45d882f7bafe4b9634a5b0bdb4055abd3ab",
15901595
"lessonContentHash": null
15911596
},
@@ -1643,6 +1648,7 @@
16431648
"license": "proprietary-project",
16441649
"licenseUrl": null,
16451650
"fixtureId": "learning-automation-domain-v1",
1651+
"promptPath": "assets/brand/visuals/prompts/automation-v1.txt",
16461652
"promptHash": "sha256-2f378e592935ce87e9eed1ae357053602f5e9a625cf8a656d28f5dbff71165b7",
16471653
"lessonContentHash": null
16481654
},
@@ -1700,6 +1706,7 @@
17001706
"license": "proprietary-project",
17011707
"licenseUrl": null,
17021708
"fixtureId": "developer-literacy-domain-v1",
1709+
"promptPath": "assets/brand/visuals/prompts/developer-literacy-v1.txt",
17031710
"promptHash": "sha256-85e38fd1ca4b81e80c950874eb38b7ad64a9fe79549dc36514be63d4bed709aa",
17041711
"lessonContentHash": null
17051712
},
@@ -1757,6 +1764,7 @@
17571764
"license": "proprietary-project",
17581765
"licenseUrl": null,
17591766
"fixtureId": "ai-integration-domain-v1",
1767+
"promptPath": "assets/brand/visuals/prompts/ai-integration-v1.txt",
17601768
"promptHash": "sha256-51f558f4635cfe113f30a3771b3d16437bd96f712cb726b65347c3f0e32c7479",
17611769
"lessonContentHash": null
17621770
},

assets/brand/visuals/manifest.schema.json

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,24 @@
5454
"provenance": {
5555
"type": "object",
5656
"additionalProperties": false,
57-
"required": ["author", "license", "licenseUrl", "fixtureId"],
57+
"required": ["author", "license", "licenseUrl", "fixtureId", "promptHash"],
5858
"properties": {
5959
"author": { "type": "string", "minLength": 1 },
6060
"license": { "type": "string", "minLength": 1 },
61-
"licenseUrl": { "type": ["string", "null"] },
61+
"licenseUrl": {
62+
"anyOf": [
63+
{ "type": "string", "format": "uri", "pattern": "^https://" },
64+
{ "type": "null" }
65+
]
66+
},
6267
"fixtureId": { "type": "string", "minLength": 1 },
63-
"promptHash": { "type": ["string", "null"] },
68+
"promptPath": { "type": ["string", "null"] },
69+
"promptHash": {
70+
"anyOf": [
71+
{ "type": "string", "pattern": "^sha256-[0-9a-f]{64}$" },
72+
{ "type": "null" }
73+
]
74+
},
6475
"lessonContentHash": { "type": ["string", "null"] }
6576
}
6677
},

docs/skills/ops/product/branding.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ whenToUse: 새 UI 컴포넌트 추가, 색/반지름/그림자 변경, 랜딩/
6868
- 실제 제품 screenshot과 학습 결과 이미지를 mascot보다 우선하는 product proof로 사용한다. fake terminal, fake editor, emoji primary icon을 새로 만들지 않는다.
6969
- 제품 screenshot은 `assets/brand/visuals/manifest.json``fixtureId`, viewport, theme가 캡처 입력의 SSOT다. `tests/assets/captureProductVisuals.py --check`는 각 fixture를 격리 실행해 canonical PNG와 fresh pixels가 같은지, 사용자 home path·email·credential 신호가 보이지 않는지 검사한다. 제품 UI를 바꾼 뒤에는 구현 commit이 clean한 상태에서 `--update`로 원본, source hash·git head·source-set hash, AVIF/WebP와 Landing·Editor mirror를 함께 갱신한다. 브라우저 output을 수동 복사하거나 generated variant만 교체하지 않는다.
7070
- 학습 결과 증명은 `assets/brand/visuals/outcomes/fixtures.json`의 고정 입력과 `assets/brand/tools/captureOutcomeProofs.py`가 소유한다. outcome proof는 입력, 실행 결과, 검증 영수증을 한 프레임에서 비교하고 색만으로 성공을 표현하지 않는다. `--check`는 canonical PNG와 fresh fixture pixels를 대조하며 `--update`는 clean 구현 commit을 sourceGitHead로 결속한 뒤 AVIF/WebP와 Landing·Editor mirror를 함께 갱신한다.
71+
- 생성 raster는 `assets/brand/visuals/prompts/` 안의 `promptPath`와 실제 파일 SHA-256인 `promptHash`를 함께 기록한다. `proprietary-project` 자산은 `licenseUrl: null`만 허용하고, `licensedMedia`는 구체적인 license 이름과 HTTPS 근거 URL이 없으면 public manifest에 넣지 않는다.
7172
- Landing의 목표 경로와 Editor의 해당 레슨은 outcome asset ID를 `assets/brand/visuals/manifest.json`에서 해석한다. 제품 화면이나 장식 illustration을 실제 결과 증명 대신 사용하지 않는다.
7273
- 예측 카드는 학습 경험에 다시 도입하지 않는다. 학습 흐름은 설명, 직접 수정, 실행, 오류 수정, 강한 검증, 실무 변주다.
7374
- 학습 본문 정리 과정은 `#`, 괄호, 대괄호, 연산자처럼 코드 학습에 필요한 문자를 삭제하지 않는다. 인라인 코드는 semantic code element로 남기고 조각 경계 공백을 보존한다.

editor/public/visuals/manifest.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schemaVersion": 1,
3-
"sourceManifestHash": "sha256-c4242eb050f0977c3335a34c406a5ee9a28f91897a7f9bc6ecf77e7bad0bb90e",
3+
"sourceManifestHash": "sha256-4735270950f5d042bb6099145d0336d7a100d1a84383fb7ec0bae00d77dfeac5",
44
"assets": [
55
{
66
"id": "runLearningDetail",
@@ -2060,6 +2060,7 @@
20602060
"license": "proprietary-project",
20612061
"licenseUrl": null,
20622062
"fixtureId": "python-fundamentals-domain-v1",
2063+
"promptPath": "assets/brand/visuals/prompts/python-fundamentals-v1.txt",
20632064
"promptHash": "sha256-45246801d7843b7af2cc0174e818e81a9d9e0d1925a4e7b738222dce3e4e5d38",
20642065
"lessonContentHash": null
20652066
},
@@ -2186,6 +2187,7 @@
21862187
"license": "proprietary-project",
21872188
"licenseUrl": null,
21882189
"fixtureId": "data-analysis-domain-v1",
2190+
"promptPath": "assets/brand/visuals/prompts/data-analysis-v1.txt",
21892191
"promptHash": "sha256-c737f07e956cf2e3c97cdec7ff696187f3585c3d665865623c2873a344bba484",
21902192
"lessonContentHash": null
21912193
},
@@ -2309,6 +2311,7 @@
23092311
"license": "proprietary-project",
23102312
"licenseUrl": null,
23112313
"fixtureId": "data-visualization-domain-v1",
2314+
"promptPath": "assets/brand/visuals/prompts/data-visualization-v1.txt",
23122315
"promptHash": "sha256-e850f31ca2c0d2bb88f54fe8d763a0bdeec70ed29732a5d466f8746a04ed35f1",
23132316
"lessonContentHash": null
23142317
},
@@ -2432,6 +2435,7 @@
24322435
"license": "proprietary-project",
24332436
"licenseUrl": null,
24342437
"fixtureId": "statistics-machine-learning-domain-v1",
2438+
"promptPath": "assets/brand/visuals/prompts/statistics-ml-v1.txt",
24352439
"promptHash": "sha256-882f948c62f95971f176cc50ee33b87daead4134ea0bcd2130c9bcba9ac4d0a5",
24362440
"lessonContentHash": null
24372441
},
@@ -2555,6 +2559,7 @@
25552559
"license": "proprietary-project",
25562560
"licenseUrl": null,
25572561
"fixtureId": "image-vision-domain-v1",
2562+
"promptPath": "assets/brand/visuals/prompts/image-vision-v1.txt",
25582563
"promptHash": "sha256-73fc05ae505bab09936dba44d712c45d882f7bafe4b9634a5b0bdb4055abd3ab",
25592564
"lessonContentHash": null
25602565
},
@@ -2678,6 +2683,7 @@
26782683
"license": "proprietary-project",
26792684
"licenseUrl": null,
26802685
"fixtureId": "learning-automation-domain-v1",
2686+
"promptPath": "assets/brand/visuals/prompts/automation-v1.txt",
26812687
"promptHash": "sha256-2f378e592935ce87e9eed1ae357053602f5e9a625cf8a656d28f5dbff71165b7",
26822688
"lessonContentHash": null
26832689
},
@@ -2801,6 +2807,7 @@
28012807
"license": "proprietary-project",
28022808
"licenseUrl": null,
28032809
"fixtureId": "developer-literacy-domain-v1",
2810+
"promptPath": "assets/brand/visuals/prompts/developer-literacy-v1.txt",
28042811
"promptHash": "sha256-85e38fd1ca4b81e80c950874eb38b7ad64a9fe79549dc36514be63d4bed709aa",
28052812
"lessonContentHash": null
28062813
},
@@ -2924,6 +2931,7 @@
29242931
"license": "proprietary-project",
29252932
"licenseUrl": null,
29262933
"fixtureId": "ai-integration-domain-v1",
2934+
"promptPath": "assets/brand/visuals/prompts/ai-integration-v1.txt",
29272935
"promptHash": "sha256-51f558f4635cfe113f30a3771b3d16437bd96f712cb726b65347c3f0e32c7479",
29282936
"lessonContentHash": null
29292937
},

landing/static/visuals/manifest.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schemaVersion": 1,
3-
"sourceManifestHash": "sha256-c4242eb050f0977c3335a34c406a5ee9a28f91897a7f9bc6ecf77e7bad0bb90e",
3+
"sourceManifestHash": "sha256-4735270950f5d042bb6099145d0336d7a100d1a84383fb7ec0bae00d77dfeac5",
44
"assets": [
55
{
66
"id": "runLearningDetail",
@@ -2060,6 +2060,7 @@
20602060
"license": "proprietary-project",
20612061
"licenseUrl": null,
20622062
"fixtureId": "python-fundamentals-domain-v1",
2063+
"promptPath": "assets/brand/visuals/prompts/python-fundamentals-v1.txt",
20632064
"promptHash": "sha256-45246801d7843b7af2cc0174e818e81a9d9e0d1925a4e7b738222dce3e4e5d38",
20642065
"lessonContentHash": null
20652066
},
@@ -2186,6 +2187,7 @@
21862187
"license": "proprietary-project",
21872188
"licenseUrl": null,
21882189
"fixtureId": "data-analysis-domain-v1",
2190+
"promptPath": "assets/brand/visuals/prompts/data-analysis-v1.txt",
21892191
"promptHash": "sha256-c737f07e956cf2e3c97cdec7ff696187f3585c3d665865623c2873a344bba484",
21902192
"lessonContentHash": null
21912193
},
@@ -2309,6 +2311,7 @@
23092311
"license": "proprietary-project",
23102312
"licenseUrl": null,
23112313
"fixtureId": "data-visualization-domain-v1",
2314+
"promptPath": "assets/brand/visuals/prompts/data-visualization-v1.txt",
23122315
"promptHash": "sha256-e850f31ca2c0d2bb88f54fe8d763a0bdeec70ed29732a5d466f8746a04ed35f1",
23132316
"lessonContentHash": null
23142317
},
@@ -2432,6 +2435,7 @@
24322435
"license": "proprietary-project",
24332436
"licenseUrl": null,
24342437
"fixtureId": "statistics-machine-learning-domain-v1",
2438+
"promptPath": "assets/brand/visuals/prompts/statistics-ml-v1.txt",
24352439
"promptHash": "sha256-882f948c62f95971f176cc50ee33b87daead4134ea0bcd2130c9bcba9ac4d0a5",
24362440
"lessonContentHash": null
24372441
},
@@ -2555,6 +2559,7 @@
25552559
"license": "proprietary-project",
25562560
"licenseUrl": null,
25572561
"fixtureId": "image-vision-domain-v1",
2562+
"promptPath": "assets/brand/visuals/prompts/image-vision-v1.txt",
25582563
"promptHash": "sha256-73fc05ae505bab09936dba44d712c45d882f7bafe4b9634a5b0bdb4055abd3ab",
25592564
"lessonContentHash": null
25602565
},
@@ -2678,6 +2683,7 @@
26782683
"license": "proprietary-project",
26792684
"licenseUrl": null,
26802685
"fixtureId": "learning-automation-domain-v1",
2686+
"promptPath": "assets/brand/visuals/prompts/automation-v1.txt",
26812687
"promptHash": "sha256-2f378e592935ce87e9eed1ae357053602f5e9a625cf8a656d28f5dbff71165b7",
26822688
"lessonContentHash": null
26832689
},
@@ -2801,6 +2807,7 @@
28012807
"license": "proprietary-project",
28022808
"licenseUrl": null,
28032809
"fixtureId": "developer-literacy-domain-v1",
2810+
"promptPath": "assets/brand/visuals/prompts/developer-literacy-v1.txt",
28042811
"promptHash": "sha256-85e38fd1ca4b81e80c950874eb38b7ad64a9fe79549dc36514be63d4bed709aa",
28052812
"lessonContentHash": null
28062813
},
@@ -2924,6 +2931,7 @@
29242931
"license": "proprietary-project",
29252932
"licenseUrl": null,
29262933
"fixtureId": "ai-integration-domain-v1",
2934+
"promptPath": "assets/brand/visuals/prompts/ai-integration-v1.txt",
29272935
"promptHash": "sha256-51f558f4635cfe113f30a3771b3d16437bd96f712cb726b65347c3f0e32c7479",
29282936
"lessonContentHash": null
29292937
},

0 commit comments

Comments
 (0)