From 7b9ae307a5141607faac8f3584b7a58dddcb4deb Mon Sep 17 00:00:00 2001 From: Chris Dumas Date: Mon, 25 May 2026 13:16:57 +0000 Subject: [PATCH] docs: add operating cadence and clean styling --- .gitignore | 3 + 09-operating-cadence-and-batch-plan.md | 65 +++ PROJECT.md | 2 + README.md | 2 + VIKUNJA.md | 1 + src/app/globals.scss | 547 ------------------------- 6 files changed, 73 insertions(+), 547 deletions(-) create mode 100644 09-operating-cadence-and-batch-plan.md delete mode 100644 src/app/globals.scss diff --git a/.gitignore b/.gitignore index e356bad..90bb5c2 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ prisma/dev.db # Misc .cache +tsconfig.tsbuildinfo +.openclaw/ +.trash/ diff --git a/09-operating-cadence-and-batch-plan.md b/09-operating-cadence-and-batch-plan.md new file mode 100644 index 0000000..382a3d5 --- /dev/null +++ b/09-operating-cadence-and-batch-plan.md @@ -0,0 +1,65 @@ +# 09. Operating Cadence and Batch Plan + +## Purpose + +Keep the holiday-property-booking board moving in a predictable rhythm so Neo always has clear implementation work and the project does not stall between batches. + +## Cadence + +### Every hour: Neo takes the top Ready ticket + +- Neo takes the top ticket in `Ready for Dev`. +- Neo follows the normal dev procedure for that ticket: + - move it to `In Dev` + - branch from `develop` + - implement the work + - push the branch + - report blockers or validation-ready evidence + - merge the feature branch back to `develop` when the implementation slice is done + - leave the merge-complete comment and hand the ticket forward for validation or promotion according to the playbook +- When the ticket is finished, post a Discord-ready completion summary with the ticket ID, what changed, branch/merge state, and the next step or blocker. +- Neo works one ticket at a time unless Morpheus explicitly batches related work. + +### Every hour: Morpheus reviews the lanes + +- Review the full board for: + - stalled `In Dev` work + - validation work waiting on `Ready for Test`, `Deploying to Dev`, or `In QA` + - release work waiting on `Ready for QA Promotion`, `Deploying to QA`, `QA Deployed`, `Ready for Production`, or `Included in Next Release` + - blockers that need triage + - queue depth in `Ready for Dev` +- If a ticket is clearly stalled, route it to the correct owner and keep the handoff explicit. +- Morpheus keeps the promotion side of the flow: wait for Neo's merge to `develop`, check the develop build, then promote `develop -> qa` when ready. + +## Batch Rule + +- Count the tickets that have not yet been worked on, meaning the tickets still waiting in `Backlog` or `Ready for Dev`. +- If that count is less than 5, continue the project by creating the next batch of work. +- The next batch should come from the next unresolved phase in the project plan, in dependency order. +- Keep the batch grouped so the work stays coherent and reviewable. +- Keep refilling the ready queue until there are at least 5 unworked tickets, or until the next phase is exhausted. + +## Routing Rule + +- For each new ready ticket, add a paste-ready comment that states: + - the current lane + - the target lane + - the next responsible agent + - the next concrete action +- Send Neo the actual handoff directly; the ticket comment is the audit trail, not the delivery channel. +- Keep the ticket comment short and actionable so it makes sense even if someone reads it later without the surrounding chat. +- Keep lane moves and comments aligned with the playbook lane model; do not skip the comment even when the move is automated or obvious. +- Do not leave the queue in a state where no ticket is clearly assigned. + +## Acceptance Criteria + +- Neo always has a top ready ticket to pick up on the 30-minute cadence. +- Neo always has a top ready ticket to pick up on the hourly cadence. +- Neo posts a completion summary to Discord when a ticket finishes. +- Neo still owns merge-back-to-`develop` for feature work. +- Morpheus still owns `develop -> qa` promotion after develop is green. +- Ticket moves and comments stay consistent with the playbook lane model. +- Morpheus can see the full lane state on the hourly review. +- The ready queue is replenished before it drops below 5 unworked tickets. +- New batches are created in dependency order instead of ad hoc. +- The board never stalls because the next group of tickets was not prepared. diff --git a/PROJECT.md b/PROJECT.md index e506f97..9474153 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -33,7 +33,9 @@ Phase 1 scaffold started from the approved planning docs, and the Vikunja board - The first build tickets are queued on the board, with later phase work staged behind them - Post-dev flow is documented so implementation tickets always merge to `develop`, then hand off into test/validation before QA promotion - New functionality should extend the Playwright suite so browser regression coverage grows with the app +- Operating cadence is documented so Neo takes the top `Ready for Dev` ticket every hour, posts a completion summary to Discord when done, Morpheus reviews the lanes every hour, and the queue is refilled before it drops below 5 unworked tickets ## Next Build Step - Start with `VIK-108`, then work through `VIK-109` to `VIK-112` in order before pulling from the backlog queue. +- Once fewer than 5 tickets remain unworked, create the next batch from the next unresolved phase instead of letting the queue drain. diff --git a/README.md b/README.md index 679ff86..9374473 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ The project has been onboarded to Vikunja and the board now uses the playbook la The next public work is queued as tickets, with `VIK-112` staged as the next active item after the current slice. Implementation tickets are expected to merge back to `develop` first, then hand off into `Ready for Test` / `Deploying to Dev` before Trinity validation and later QA promotion. Any new feature work should also update the Playwright suite so the browser tests become the main regression check as coverage expands. +Operating cadence is now defined in `09-operating-cadence-and-batch-plan.md`: Neo pulls the top `Ready for Dev` ticket every hour, posts a completion summary to Discord when finished, Morpheus reviews the lanes every hour, and the ready queue is replenished when fewer than 5 tickets remain unworked. ## Working Rule @@ -25,6 +26,7 @@ We will not build this in one shot. Each numbered document in this folder define 6. `06-admin-console.md` 7. `07-seo-accessibility-performance.md` 8. `08-implementation-plan-and-launch-readiness.md` +9. `09-operating-cadence-and-batch-plan.md` ## Source diff --git a/VIKUNJA.md b/VIKUNJA.md index aa92b78..d013763 100644 --- a/VIKUNJA.md +++ b/VIKUNJA.md @@ -46,6 +46,7 @@ This board is normalized to the shared playbook lane model. - Feature work now lives on this board and should be tracked as separate tickets. - Use the playbook lane names exactly when routing work. - When a ticket finishes `In Dev`, Neo merges the feature branch back to `develop`, leaves a merge-complete comment, and hands the ticket forward for validation rather than marking it done. +- When Morpheus routes work, send Neo the handoff directly and leave the ticket comment as a concise record of the lane change and next action; do not rely on the bucket comment as the only delivery path. - After the merge, move the ticket into `Ready for Test` and then `Deploying to Dev` while the dev build/deploy proves the change. - Trinity handles validation once the dev environment is ready, and the ticket only moves forward after the live check passes. - QA promotion is a separate step after dev validation, not part of the merge itself. diff --git a/src/app/globals.scss b/src/app/globals.scss deleted file mode 100644 index 90a9620..0000000 --- a/src/app/globals.scss +++ /dev/null @@ -1,547 +0,0 @@ -$body-bg: #f4efe7; -$body-color: #1a1714; -$primary: #7a543d; -$secondary: #2e6661; -$success: #2f6b43; -$warning: #b07d24; -$danger: #a63d3d; -$border-radius: 1rem; -$font-family-sans-serif: "Avenir Next", "Segoe UI", sans-serif; -$headings-font-family: "Iowan Old Style", "Palatino Linotype", Georgia, serif; - -@import "bootstrap/scss/bootstrap"; - -:root { - --shell-bg: #f4efe7; - --panel-bg: rgba(255, 255, 255, 0.72); - --panel-border: rgba(26, 23, 20, 0.08); - --accent: #7a543d; - --accent-2: #2e6661; - --text-muted: #63594f; - --shadow: 0 24px 80px rgba(23, 19, 14, 0.12); -} - -* { - box-sizing: border-box; -} - -html { - scroll-behavior: smooth; -} - -body { - min-height: 100vh; - margin: 0; - background: - radial-gradient(circle at top left, rgba(122, 84, 61, 0.18), transparent 30%), - radial-gradient(circle at 80% 10%, rgba(46, 102, 97, 0.18), transparent 24%), - var(--shell-bg); -} - -a { - color: inherit; - text-decoration: none; -} - -main { - position: relative; -} - -.app-shell { - min-height: 100vh; - padding: 1.25rem; -} - -.surface { - max-width: 1180px; - margin: 0 auto; - border: 1px solid var(--panel-border); - border-radius: 1.75rem; - background: var(--panel-bg); - box-shadow: var(--shadow); - backdrop-filter: blur(18px); -} - -.site-header, -.site-footer, -.hero, -.section-shell { - padding: 1.5rem; -} - -.site-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - border-bottom: 1px solid var(--panel-border); -} - -.brand-lockup { - display: flex; - align-items: center; - gap: 1rem; -} - -.brand-mark { - display: inline-grid; - place-items: center; - width: 3rem; - height: 3rem; - border-radius: 999px; - background: linear-gradient(135deg, var(--accent), var(--accent-2)); - color: #fff; - font-weight: 700; - letter-spacing: 0.08em; -} - -.brand-kicker, -.footer-label, -.section-eyebrow { - margin: 0 0 0.25rem; - font-size: 0.72rem; - letter-spacing: 0.18em; - text-transform: uppercase; - color: var(--text-muted); -} - -.brand-lockup h1 { - margin: 0; - font-size: 1.05rem; -} - -.site-nav { - display: flex; - flex-wrap: wrap; - gap: 0.75rem; -} - -.site-nav a { - padding: 0.55rem 0.85rem; - border: 1px solid rgba(26, 23, 20, 0.12); - border-radius: 999px; - font-size: 0.92rem; - color: var(--text-muted); - transition: - transform 160ms ease, - border-color 160ms ease, - background-color 160ms ease; -} - -.site-nav a:hover, -.site-nav a:focus-visible { - transform: translateY(-1px); - border-color: rgba(122, 84, 61, 0.35); - background: rgba(255, 255, 255, 0.8); - color: var(--body-color); -} - -.hero { - display: grid; - grid-template-columns: 1.5fr 1fr; - gap: 1.5rem; - align-items: stretch; -} - -.hero-copy, -.hero-panel, -.info-card, -.phase-card, -.data-card { - border: 1px solid var(--panel-border); - border-radius: 1.5rem; - background: rgba(255, 255, 255, 0.78); -} - -.hero-copy { - padding: 2rem; -} - -.hero-copy h2 { - margin: 0 0 1rem; - font-size: clamp(2.2rem, 4vw, 4.2rem); - line-height: 0.95; - letter-spacing: -0.04em; -} - -.hero-copy p { - max-width: 60ch; - color: var(--text-muted); - font-size: 1.06rem; -} - -.hero-actions { - display: flex; - flex-wrap: wrap; - gap: 0.75rem; - margin-top: 1.5rem; -} - -.hero-actions .btn { - border-radius: 999px; - padding-inline: 1.1rem; -} - -.hero-points { - display: grid; - gap: 0.55rem; - margin: 1.5rem 0 0; - padding-left: 1.1rem; - color: var(--text-muted); -} - -.hero-panel { - display: grid; - gap: 1rem; - padding: 1.5rem; -} - -.search-panel { - display: grid; - gap: 0.85rem; - padding: 1rem; - border-radius: 1.25rem; - background: rgba(255, 255, 255, 0.9); - border: 1px solid rgba(26, 23, 20, 0.08); -} - -.search-field { - display: grid; - gap: 0.35rem; - color: var(--text-muted); - font-size: 0.92rem; -} - -.search-field input, -.contact-form input, -.contact-form textarea { - width: 100%; - border: 1px solid rgba(26, 23, 20, 0.14); - border-radius: 0.9rem; - padding: 0.8rem 0.95rem; - background: rgba(255, 255, 255, 0.94); - color: var(--body-color); -} - -.search-field input:focus, -.contact-form input:focus, -.contact-form textarea:focus { - outline: 2px solid rgba(122, 84, 61, 0.28); - outline-offset: 2px; -} - -.info-card, -.phase-card, -.data-card, -.content-card, -.property-card, -.testimonial-card { - padding: 1rem; -} - -.metric-grid, -.phase-grid, -.data-grid, -.property-grid, -.content-grid, -.testimonial-grid, -.card-stack, -.content-stack { - display: grid; - gap: 1rem; -} - -.metric-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.metric { - padding: 1rem; - border-radius: 1rem; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(246, 240, 231, 0.9)); -} - -.metric strong { - display: block; - margin-bottom: 0.3rem; - font-size: 1.6rem; -} - -.section-heading h2 { - margin: 0; - font-size: clamp(1.5rem, 2vw, 2.1rem); -} - -.section-description { - max-width: 65ch; - margin: 0.5rem 0 0; - color: var(--text-muted); -} - -.phase-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.phase-card h3, -.data-card h3 { - margin-top: 0; - font-size: 1.05rem; -} - -.phase-card ul, -.data-card ul { - margin: 0.75rem 0 0; - padding-left: 1.1rem; - color: var(--text-muted); -} - -.data-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.property-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.property-card { - display: grid; - gap: 0.9rem; - border: 1px solid var(--panel-border); - border-radius: 1.35rem; - background: rgba(255, 255, 255, 0.82); -} - -.property-card-top { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 1rem; -} - -.property-card h3, -.content-card h3, -.testimonial-card strong { - margin: 0; -} - -.property-price { - display: inline-flex; - align-items: center; - padding: 0.35rem 0.7rem; - border-radius: 999px; - background: rgba(46, 102, 97, 0.12); - color: var(--accent-2); - font-size: 0.85rem; - white-space: nowrap; -} - -.property-metrics { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 0.75rem; - margin: 0; -} - -.property-metrics div { - padding: 0.75rem; - border-radius: 0.95rem; - background: rgba(244, 239, 231, 0.88); -} - -.property-metrics dt { - color: var(--text-muted); - font-size: 0.78rem; - text-transform: uppercase; - letter-spacing: 0.14em; -} - -.property-metrics dd { - margin: 0.25rem 0 0; - font-size: 1rem; - font-weight: 700; -} - -.tag-list, -.link-list { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - margin: 0; - padding: 0; - list-style: none; -} - -.tag-list li { - padding: 0.32rem 0.62rem; - border-radius: 999px; - background: rgba(122, 84, 61, 0.12); - color: var(--accent); - font-size: 0.82rem; -} - -.content-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.content-grid-tight { - align-items: flex-start; -} - -.content-card, -.testimonial-card { - border: 1px solid var(--panel-border); - border-radius: 1.35rem; - background: rgba(255, 255, 255, 0.82); -} - -.content-card p:last-child, -.testimonial-card p:last-child { - margin-bottom: 0; -} - -.inline-link { - color: var(--accent-2); - text-decoration: underline; - text-underline-offset: 0.2em; -} - -.testimonial-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.testimonial-card { - display: grid; - gap: 1rem; -} - -.testimonial-card footer { - display: grid; - gap: 0.15rem; - color: var(--text-muted); -} - -.cta-band, -.page-hero { - border: 1px solid var(--panel-border); - border-radius: 1.5rem; - background: rgba(255, 255, 255, 0.82); -} - -.cta-band { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - padding: 1.1rem 1.25rem; -} - -.page-hero { - margin: 1.5rem; - padding: 1.5rem; -} - -.page-hero h2 { - margin: 0 0 0.6rem; - font-size: clamp(2rem, 4vw, 3.5rem); - line-height: 0.98; - letter-spacing: -0.04em; -} - -.page-layout { - display: grid; - grid-template-columns: minmax(0, 1.4fr) minmax(300px, 0.75fr); - gap: 0.5rem; -} - -.page-layout .section-shell { - padding-top: 0; -} - -.contact-form { - display: grid; - gap: 0.9rem; -} - -.contact-form label { - display: grid; - gap: 0.35rem; - color: var(--text-muted); -} - -.contact-form-message { - grid-column: 1 / -1; -} - -.contact-aside { - display: grid; - gap: 1rem; - align-content: start; - padding: 1.5rem 1.5rem 1.5rem 0; -} - -.content-sidebar { - display: grid; - gap: 1rem; - align-content: start; -} - -.site-footer { - display: flex; - justify-content: space-between; - gap: 1rem; - border-top: 1px solid var(--panel-border); - color: var(--text-muted); -} - -.site-footer p { - margin: 0; -} - -@media (max-width: 900px) { - .hero, - .phase-grid, - .data-grid, - .property-grid, - .content-grid, - .testimonial-grid, - .page-layout { - grid-template-columns: 1fr; - } - - .site-header, - .site-footer, - .cta-band { - flex-direction: column; - align-items: flex-start; - } - - .contact-aside { - padding: 0 1.5rem 1.5rem; - } -} - -@media (max-width: 640px) { - .app-shell { - padding: 0.75rem; - } - - .site-header, - .hero, - .section-shell, - .site-footer { - padding: 1rem; - } - - .page-hero { - margin: 0.75rem; - padding: 1rem; - } - - .metric-grid { - grid-template-columns: 1fr; - } - - .property-metrics { - grid-template-columns: 1fr; - } -}