A digest locator carried observed_hash + emit_ts but nothing DATING the
snapshot, so a consumer could not tell a fresh snapshot from one already
superseded at delivery without a tool call (wake-pilot finding
fw-wake-digest-snapshot-lag: seq 56 rendered "(none)" from a board revision
superseded ~5s before delivery by one adding a FLEET STOP block).
Additive + backward-compatible:
- detector.sh: invoke the W4 source adapter with fd 3 -> temp file; the
adapter MAY write {"snapshot_sha": "<git commit sha>", "snapshot_ts":
<epoch>}. Out-of-band is load-bearing: stdout is hashed by the delta
gate, so an in-band tip-commit sha would advance observed_hash on every
unrelated push. Metadata is ADVISORY and validated (sha ^[0-9a-f]{7,64}$,
ts number); malformed metadata drops LOUDLY but never fails the poll or
suppresses the wake. Valid fields join the enqueue locators. An adapter
that never writes fd 3 is byte-identical legacy behavior.
- digest.sh: _locator_line renders snapshot_sha=/snapshot_ts= (scrubbed)
beside observed_hash=; snapshot_sha+path upgrades the actionable-tier
re-verify hint to one-call `git show <snapshot_sha>:<path>`. With
emit_ts already in the header, snapshot age is local arithmetic.
- tests: detector D10 (fields land in locators; metadata-only change is
NOT a delta) + D11 (malformed metadata: loud drop, wake still fires, no
fields); digest Q10 (orientation dating render, no-vestige sibling,
actionable re-verify upgrade). manifest 0.6.12; watch-list schema
untouched ([1,1]); store/reconcile/beacon unchanged.
Closes#940
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
GLPI helpdesk workflow skills written against the portable
tools/glpi/ tooling (session-init.sh, ticket-list.sh, ticket-create.sh),
cross-linked via [[glpi-*]]:
- glpi-solve — close a ticket by setting status Solved (5); GLPI auto-closes
- glpi-followup — add a followup via the top-level /ITILFollowup endpoint
- glpi-sweep — read-only hunt for done-but-open tickets needing Solve
- glpi-list — query tickets by status/recency
- glpi-create — open a new ticket
Core rule encoded: completing work means setting status Solved, not just
posting a resolution followup (a followup documents; only Solved auto-closes).
Note: illustrative examples in the bodies are USC-flavored (M2M / helpdesk
ticket numbers) and can be genericized in review if preferred.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_019GjBgrb9tHgvq414Fqj37c
Completes the bootstrap repo migration with remaining files:
- PowerShell scripts (.ps1) for Windows support (bin/ + tools/)
- Runtime adapters (claude, codex, generic, pi)
- Guides (17 .md files) and profiles (domains, tech-stacks, workflows)
- Wizard test suite (6 test files from bootstrap tests/)
- Memory placeholder, audit history
Bootstrap repo (mosaic/bootstrap) is now fully superseded:
- All 335 files accounted for
- 5 build config files (package.json, tsconfig, etc.) not needed —
monorepo has its own at packages/mosaic/
- skills-local/ superseded by monorepo skills/ with mosaic-* naming
- src/ already lives at packages/mosaic/src/
Kaniko fails when COPY --from=builder references a path that doesn't
exist. The web app had no public/ directory, causing build-web to fail
with 'no such file or directory' on the public assets COPY step.
Publish pipeline:
- Add publish-npm step to .woodpecker/publish.yml — publishes all
@mosaic/* packages to Gitea npm registry on main push/tag
- Requires gitea_npm_token Woodpecker secret (package:write scope)
- publish-npm runs after build, parallel with Docker image builds
- pnpm publish resolves workspace:* to concrete versions automatically
Package configuration:
- All 20 packages versioned at 0.0.1-alpha.1
- publishConfig added to all packages (Gitea registry, public access)
- files field added to all packages (ship only dist/)
- @mosaic/forge includes pipeline/ assets in published package
Meta package (@mosaic/mosaic):
- Now depends on @mosaic/forge, @mosaic/macp, @mosaic/prdy,
@mosaic/quality-rails, @mosaic/types
- npm install @mosaic/mosaic pulls in the standalone framework
Build fixes:
- Fix forge and macp tsconfig rootDir: '.' -> 'src' so dist/index.js
resolves correctly (was dist/src/index.js)
- Exclude __tests__ and vitest.config from build includes
- Clean stale build artifacts from old rootDir config
Required Woodpecker secret:
woodpecker secret add mosaic/mosaic-stack \
--name gitea_npm_token --value '<token>' \
--event push,manual,tag
Skills:
- Rename all repo skills to mosaic-<name> convention (jarvis -> mosaic-jarvis, etc.)
- Update frontmatter name: fields to match directory names
- New mosaic-board skill: standalone Board of Directors multi-persona review
- New mosaic-forge skill: standalone Forge specialist pipeline
- New mosaic-prdy skill: PRD lifecycle (init/update/validate/status)
Wizard (packages/mosaic):
- Add mosaic-board, mosaic-forge, mosaic-prdy, mosaic-standards, mosaic-macp
to RECOMMENDED_SKILLS
- Add new skills to SKILL_CATEGORIES for categorized browsing
Framework scripts (~/.config/mosaic/bin):
- mosaic (launcher): load skills from both skills/ and skills-local/ for Pi
- mosaic-doctor: add --fix flag for auto-wiring skills into all harnesses,
Pi skill dir checks, Pi settings.json validation, mosaic-* presence checks
- mosaic-sync-skills: add Pi as 4th link target, fix find to follow symlinks
in skills-local/, harden is_mosaic_skill_name() with -L fallback
- mosaic-link-runtime-assets: add Pi settings.json skills path patching,
remove duplicate extension copy (launcher --extension is single source)
- mosaic-migrate-local-skills: add Pi to skill_roots, fix find for symlinks
YAML fixes:
- Quote description values containing colons in mosaic-deploy and
mosaic-woodpecker SKILL.md frontmatter (fixes Pi parse errors)