revise(02-04): fix inklecate binary path + drop unused .ink + add last_fragment_title slot

- BLOCKER 4: inklecateBinary() now resolves node_modules/inklecate/bin/inklecate{,.exe};
  the previous path (inklecate-windows/, inklecate-mac/, inklecate-linux/) does not
  exist in the package — fallback verification of Assumption A6 would have masked
  the wrapper-API failure.
- W3: removed lura-greeting-template.ink from files_modified (never authored).
- W4: added last_fragment_title to INK_VARIABLE_MAP (extracts first sentence of the
  most-recently-harvested fragment) so the must_haves slot promise is fulfilled.
This commit is contained in:
2026-05-09 02:56:50 -04:00
parent 63d2d8d5f7
commit f7428da299
@@ -13,7 +13,6 @@ files_modified:
- content/dialogue/season1/lura-mid.ink
- content/dialogue/season1/lura-farewell.ink
- content/dialogue/season1/compost-acknowledgements.ink
- content/dialogue/season1/lura-greeting-template.ink
- src/sim/narrative/lura-gate.ts
- src/sim/narrative/lura-gate.test.ts
- src/sim/narrative/beat-queue.ts
@@ -278,13 +277,12 @@ function findInkFiles(root) {
}
function inklecateBinary() {
// Verified at Task 1 — node_modules/inklecate/ ships per-platform binaries.
// The wrapper module exports a programmatic API; if it does not, fall through here.
const platform = process.platform;
const root = resolve(process.cwd(), 'node_modules/inklecate');
if (platform === 'win32') return resolve(root, 'inklecate-windows/inklecate.exe');
if (platform === 'darwin') return resolve(root, 'inklecate-mac/inklecate');
return resolve(root, 'inklecate-linux/inklecate');
// The wrapper API is tried first in compileAllInk; this is the fallback.
// Verified Task 1: node_modules/inklecate/bin/{inklecate,inklecate.exe} —
// a single bin/ directory holds both .NET binaries (Windows + POSIX). The
// wrapper handles platform selection internally.
const ext = process.platform === 'win32' ? '.exe' : '';
return resolve(process.cwd(), 'node_modules/inklecate/bin/inklecate' + ext);
}
export async function compileAllInk() {
@@ -538,6 +536,14 @@ export const INK_VARIABLE_MAP = {
if (frag.tags.includes('heavy')) return 'winter-rose';
return '';
},
// Per W4 — first sentence of the most-recently-harvested fragment's body, for letter prose.
last_fragment_title: (s: AppStoreShape) => {
const lastId = s.harvestedFragmentIds[s.harvestedFragmentIds.length - 1];
if (!lastId) return '';
const frag = allFragments.find((f) => f.id === lastId);
if (!frag) return '';
return frag.body.split(/[.!?]/)[0]?.trim() ?? '';
},
} as const;
export async function loadInkStory(name: 'lura-arrival' | 'lura-mid' | 'lura-farewell' | 'compost-acknowledgements'): Promise<Story> {
@@ -611,6 +617,8 @@ If `compile:ink` fails on Windows (Assumption A6 risk), DOCUMENT in SUMMARY.md a
</action>
<acceptance_criteria>
- `test -f scripts/compile-ink.mjs && grep -q "compileAllInk" scripts/compile-ink.mjs`
- `grep -q "node_modules/inklecate/bin" scripts/compile-ink.mjs` (BLOCKER 4: real binary path; not the non-existent inklecate-windows/ etc.)
- `! grep -q "inklecate-windows\|inklecate-mac\|inklecate-linux" scripts/compile-ink.mjs` (negative: stale path strings absent)
- `test -f content/dialogue/season1/lura-arrival.ink`
- `test -f content/dialogue/season1/lura-mid.ink`
- `test -f content/dialogue/season1/lura-farewell.ink`