Skip to content

feat(chronicle): append-semantics trio (hypothesis-track / stakeholder-update / customer-update)#30

Merged
argen merged 2 commits into
mainfrom
feat/chronicle-append-semantics
May 20, 2026
Merged

feat(chronicle): append-semantics trio (hypothesis-track / stakeholder-update / customer-update)#30
argen merged 2 commits into
mainfrom
feat/chronicle-append-semantics

Conversation

@argen

@argen argen commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the PM chronicle append-semantics queue from `ROADMAP.md` → Later. Three skills (`hypothesis-track`, `stakeholder-update`, `customer-update`) plus the structural exception in `chronicle.sh` they all rest on.

The invariant before: committed entries are immutable except via supersedes. Right for decisions, wrong for evidence/asks/health-signals that grow row-by-row.

The exception this PR adds: `chronicle.sh append --section "X" --content "..."` with a per-type whitelist. Decisions stay fully immutable. Hypotheses get Evidence Log only. Stakeholders get 4 sections (Open asks, Concerns, Last contact, Decision affinity). Customers get 4 (Usage shape, Health signals, Decision drivers, Stakeholders). Sections outside the whitelist still travel only via propose → commit → supersedes.

Last contact prepends (newest first → cold-read sees it; weekly `/review` staleness check finds the freshest date on its first match). Everything else appends chronologically.

Post-mutation re-validation is wired in: the entry is backed up before the append, validator runs after, and on failure the entry is restored from backup.

Commits

  • `b7e915e` — `chronicle.sh append` subcommand + 7 test cases (4 positive byte-diff, 3 negative diagnostic-substring). 33/33 chronicle harness checks pass.
  • `94e35c0` — three skills + three slash commands + `SCHEMA.md` append-exception section. Plugin manifests bumped to 51 skills / 12 commands.

Test plan

  • `scripts/test-chronicle.sh` — 33/33
  • `scripts/validate-skill.sh` on all three new skills
  • `scripts/smoke-check.sh` — 12 passed
  • Eyeball one end-to-end run against a seeded chronicle entry on `main` after merge

🤖 Generated with Claude Code

argen added 2 commits May 20, 2026 22:35
The chronicle's write-path invariant was "committed entries are immutable
except via supersedes". That works for decisions, where any change is
worth a new entry. It breaks for hypothesis Evidence Log rows,
stakeholder Open asks, and customer Health signals, which grow row by
row and should not churn the supersedes chain.

Adds a sanctioned exception: `chronicle.sh append <id> --section "X"
--content "..."`. The whitelist is per type — decisions stay fully
immutable, hypotheses get Evidence Log only, stakeholders get four
sections (Open asks, Concerns, Last contact, Decision affinity),
customers get four (Usage shape, Health signals, Decision drivers,
Stakeholders). Sections outside the whitelist still travel only via
propose → commit → supersedes.

Row shape is `- YYYY-MM-DD — <content>`. Last contact prepends (newest
first, so the /review staleness check finds the freshest date on its
first match); everything else appends chronologically. The modified
entry is re-validated post-mutation and restored from backup if the
append broke shape.

TDD: four positive cases + three negative cases under
tests/chronicle/append/. Harness extended with two test classes
(positive byte-diff, negative diagnostic-substring). 33/33 checks pass.
Three skills that drive the chronicle layer's append exception (see the
preceding commit). Each is a thin wrapper over `chronicle.sh append`
with a sharp purpose:

- hypothesis-track: appends one Evidence Log row to an open
  `type: hypothesis` entry; reads the entry's Falsifier and Prediction
  after the append and surfaces a supersedes proposal if the new row
  crossed either threshold (refutation or resolving decision).
- stakeholder-update: one section per touchpoint on a
  `type: stakeholder` entry — Last contact (prepended), Open asks,
  Concerns, or Decision affinity. Same touch hitting two sections
  becomes two append calls so the audit trail stays clean.
- customer-update: B2B-account sibling for `type: customer` entries —
  Usage shape, Health signals, Decision drivers, Stakeholders. New
  stakeholder discovered inside an account prompts the user to open a
  per-person entry; the customer row is the placeholder, not the
  record.

None of the three auto-runs supersedes or commits anything. The append
itself is automated; the threshold-crossing decisions stay
human-gated, in line with the rest of the chronicle write path.

SCHEMA.md updated with the append-exception section, per-type
whitelist table, and prepend rule for Last contact. ROADMAP.md moves
the trio from Later → Now; bet-portfolio refactor stays in Later as a
follow-on. Plugin counts bumped on both manifests.
@argen argen merged commit 3d57f4a into main May 20, 2026
1 check failed
argen added a commit that referenced this pull request May 20, 2026
… into base

When this PR was rebased onto current main (which carried the squash-
merged #30), the plugin description counts needed updating from
\"10 commands, 50 skills (37 PM + 13 cross-role)\" to
\"12 commands, 54 skills (38 PM + 16 cross-role)\". Also synced the
Codex manifest, which was lagging.

Counts are sourced from \`find skills -maxdepth 2 -name SKILL.md -type f\`
(16 cross-role) and \`find roles -path '*/skills/*/SKILL.md'\` (38 PM,
including the new hubspot-pipeline-readout).
argen added a commit that referenced this pull request May 20, 2026
…onsuming skills, wire mcpServers + install (#31)

* chore(resources): promote four resources to stable; wire used_by back-refs

The four resources scaffolded as `stretch` in PR 1 (jira, bigquery,
snowflake, hubspot) have been complete RESOURCE.md cards since they
landed — install command, auth env, capabilities table, object model,
common gotchas, fallback recipes. Flipping `status: stretch →
status: stable` after re-reading each one to confirm the content is
load-bearing.

Also updating `used_by:` back-refs on linear, jira, bigquery, snowflake,
hubspot, github to point at the consuming skills shipping in this PR
(query-issue-tracker, query-warehouse, hubspot-pipeline-readout,
decision-record, prd). The smoke-check bidirectional cross-ref now
resolves cleanly.

What stays `stretch` for now: datadog, notion, slack. Those land in
ROADMAP → Later → Resources PR 3 along with the stretch-resource
dispatcher wiring.

* feat(skills): add 3 resource-consuming skills + opt-in existing skills

Three new skills:

- `skills/query-issue-tracker/` (cross-role, resources: [linear, jira]) —
  read primitive over the team's tracker. Three call shapes: list by
  filter, drill one, active scope. Tracker detection is structural (which
  MCP server is connected); result shape is tracker-neutral (id, title,
  normalised status category, normalised priority enum). Writes stay out
  of scope — they belong to tracker-specific skills like linear-triage.

- `skills/query-warehouse/` (cross-role, resources: [bigquery, snowflake]) —
  read primitive over the team's analytics warehouse. Three call shapes:
  discover schema, estimate cost, run SQL. The kill-cost guardrail is the
  whole point — every `run` is preceded by an internal `estimate`; queries
  above the per-call byte cap (default 100 GB) are refused. SQL dialect
  is NOT translated between engines — that's a leaky abstraction; engine
  detection is enough.

- `roles/product-manager/skills/hubspot-pipeline-readout/` (resources:
  [hubspot]) — PM-specific 10-20min pass producing a one-page pipeline
  readout. Three sections in order: stage health (with rolling 90-day
  baseline comparison), segment velocity (last 30 days closed), ICP fit
  pattern (won deals vs the stated ICP claim, sourced from the chronicle
  positioning entry when present).

Frontmatter opt-ins on existing skills:

- `roles/product-manager/skills/prd/SKILL.md` — resources: [linear, jira]
  for pulling current open-issue context into the PRD when relevant.
- `skills/decision-record/SKILL.md` — resources: [github] for cross-linking
  the decision to the PR/commit that implements it.

All three new skills pass validate-skill (anatomy: Purpose, Key Concepts,
Application, Examples, Common Pitfalls, References). Smoke-check passes
with the new bidirectional cross-references resolving cleanly.

* chore(install): mcpServers manifest block, --list-resources, resource copy

Three changes that wire the resources layer into the install path and
plugin manifest so the new cards are discoverable and reachable from
installed Hornero rather than only from the repo checkout.

1. `.claude-plugin/plugin.json` gains an `mcpServers` block listing
   linear, jira, github, bigquery, snowflake, hubspot — every entry
   marked `optional: true` so Hornero stays usable when no MCP server
   is configured (graceful degradation via the Fallback section in each
   RESOURCE.md). Each entry carries install command, auth env vars, and
   used_by skills so plugin loaders can surface "this skill wants
   resource X" without parsing repo files.

2. `install.sh --list-resources` short-circuits the install flow and
   prints the resource catalog (slug, status, consumer-count) — used
   to scan availability before deciding what to wire up.

3. `install.sh` install path now copies `resources/<slug>/RESOURCE.md`
   into `<host>/hornero-resources/<slug>/` on both Claude and Codex
   targets. Read-only mirror so skills' relative cross-references
   resolve when the repo isn't on disk.

4. `scripts/smoke-check.sh` count check now includes resources in
   the expected dry-run total (skills + agents + commands + resources).

ROADMAP updated: this PR's work moves from Next → Now (under the
Resources layer summary line, which also gets a current count of stable
vs stretch and a one-line note about the cross-system primitives).
CATALOG regenerated.

This closes Resources layer PR 2 from the roadmap. Resources PR 3
(stretch resources + dispatcher wiring + SessionStart probe) stays
in Later as originally sequenced.

* fix(resources): drop aspirational mcpServers block; honest guardrail framing

Two reviewer-flagged fixes:

1. **Remove `mcpServers` block from `.claude-plugin/plugin.json`.** The
   Claude Code plugin manifest spec doesn't consume a top-level
   `mcpServers` key in this shape — MCP servers travel via `.mcp.json`
   with the standard `{command, args, env}` schema, not the
   `{optional, install, auth_env, used_by}` block I'd written. The
   block was aspirational documentation that the loader silently
   ignored; worse, the plugin description claimed it as a feature.
   Removed the block; rewrote the description to point to the
   `resources/<slug>/RESOURCE.md` cards as the source of truth for
   per-resource MCP install / auth / fallback details.

2. **Honest framing of the kill-cost guardrail in `query-warehouse`.**
   The skill prose said enforcement was "structural, not advisory" but
   a SKILL.md is instructions to an agent, not executable code. Updated
   the Common Pitfall to say so explicitly and point to where hard
   structural enforcement should actually live (warehouse-layer IAM /
   billing alerts / CI gates).

3. **Engine-routing-vs-divergent-logic note in `query-issue-tracker`.**
   The skill branches on tracker in three places in `## Application`
   (one MCP tool name per call shape). A reviewer flagged this against
   the ROADMAP "if Linear, X; if JIRA, Y more than twice, split" rule,
   but the branches are engine-routing only — same shape, different
   tool name. Added a Key Concepts note distinguishing engine routing
   (allowed, the whole point of a cross-system primitive) from
   divergent logic (the anti-pattern the rule was guarding against).
   No structural change; clarifies intent for future readers.

smoke-check still passes (12/12).

* chore(plugin): sync codex manifest, update counts after PR #30 merged into base

When this PR was rebased onto current main (which carried the squash-
merged #30), the plugin description counts needed updating from
\"10 commands, 50 skills (37 PM + 13 cross-role)\" to
\"12 commands, 54 skills (38 PM + 16 cross-role)\". Also synced the
Codex manifest, which was lagging.

Counts are sourced from \`find skills -maxdepth 2 -name SKILL.md -type f\`
(16 cross-role) and \`find roles -path '*/skills/*/SKILL.md'\` (38 PM,
including the new hubspot-pipeline-readout).
argen added a commit that referenced this pull request May 20, 2026
…#37)

Three PRs landed this session (#30 chronicle append-semantics, #31
resources layer PR 2, #32 mktemp fix) and the front-door docs hadn't
caught up. Updated counts and added coverage for what shipped:

- README:
  - Skill count: 37 → 38 PM (added hubspot-pipeline-readout in #31).
  - Cross-role count: 8 → 16 (added ingest, prep, review,
    hypothesis-track, stakeholder-update, customer-update,
    query-issue-tracker, query-warehouse).
  - Slash commands: 6 → 12 (matched the new skills).
  - Themes table: hubspot-pipeline-readout added under Operations.
  - Cross-role list restructured into four sub-groups (harness
    primitives / chronicle write+read / chronicle append-shaped /
    chronicle workflow / cross-system primitives).
  - Resources table: jira/bigquery/snowflake/hubspot promoted to
    stable with their consumer skills named; github added explicitly;
    claude.ai-native cards (canva, gmail, google-calendar,
    google-drive, intercom) folded into the stable group.
  - Chronicle section rewritten to cover all four entry types
    (decision / hypothesis / stakeholder / customer), the sourcing
    hierarchy, and the append exception with the three append-shaped
    skills.
  - New /catalog table rows for /ingest, /prep, /review, and the
    three append commands.

- DISPATCHER: "eight cross-role" → "sixteen cross-role".

- playbooks/onboarding.md, role-cheatsheet.md: skill counts updated
  to match.

No content changes outside doc strings; smoke-check still 12/12.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant