diff --git a/.gsd/DECISIONS.md b/.gsd/DECISIONS.md index a5e6d73e2..b9665def3 100644 --- a/.gsd/DECISIONS.md +++ b/.gsd/DECISIONS.md @@ -15,3 +15,8 @@ | D007 | M002 | arch | Secret forecasting scope | Current milestone only | Later milestones may change; collect when planning each | Yes — if cross-milestone friction observed | | D008 | M002 | arch | Existing key handling | Silent skip (no confirmation) | Less friction on repeated runs | Yes — if users want to rotate keys | | D009 | M002 | arch | Destination detection | Infer from project context (vercel.json, convex/ dir) | User shouldn't specify — falls back to .env | No | +<<<<<<< HEAD +======= +| D010 | M002/S01 | convention | Secrets manifest format | H3 headings per env var key with bold metadata fields and numbered guidance lists | Matches existing GSD markdown conventions (roadmap uses H2, plan uses checkboxes); H3 per key enables extractAllSections(content, 3) reuse | No | +| D011 | M002/S01 | pattern | Guidance list parsing strategy | Regex-based numbered list extraction, not parseBullets | parseBullets strips numbering which loses ordering semantics for step-by-step guidance | No | +>>>>>>> gsd/M002/S01 diff --git a/.gsd/REQUIREMENTS.md b/.gsd/REQUIREMENTS.md index 499b0792c..53ed582a2 100644 --- a/.gsd/REQUIREMENTS.md +++ b/.gsd/REQUIREMENTS.md @@ -12,7 +12,11 @@ This file is the explicit capability and coverage contract for the project. - Source: user - Primary owning slice: M002/S01 - Supporting slices: M002/S03 +<<<<<<< HEAD - Validation: unmapped +======= +- Validation: contract-proven (S01) — prompt instructions and manifest types/parser established; runtime proof pending S04 +>>>>>>> gsd/M002/S01 - Notes: Forecasting is LLM-generated at planning time, not from a static database. ### R002 — Secrets manifest file persisted in .gsd/ @@ -23,7 +27,11 @@ This file is the explicit capability and coverage contract for the project. - Source: user - Primary owning slice: M002/S01 - Supporting slices: M002/S02, M002/S03 +<<<<<<< HEAD - Validation: unmapped +======= +- Validation: contract-proven (S01) — format defined with types, parser, writer, template; runtime persistence pending S03/S04 +>>>>>>> gsd/M002/S01 - Notes: File format must be parseable by the auto-mode state machine. ### R003 — LLM-generated step-by-step guidance per key @@ -34,7 +42,11 @@ This file is the explicit capability and coverage contract for the project. - Source: user - Primary owning slice: M002/S01 - Supporting slices: M002/S02 +<<<<<<< HEAD - Validation: unmapped +======= +- Validation: contract-proven (S01) — manifest format includes guidance[], dashboardUrl, formatHint per key; quality validation pending S04 +>>>>>>> gsd/M002/S01 - Notes: Guidance quality depends on LLM knowledge of common services. Accuracy is best-effort. ### R004 — Summary screen before collection @@ -100,7 +112,11 @@ This file is the explicit capability and coverage contract for the project. - Source: inferred - Primary owning slice: M002/S01 - Supporting slices: none +<<<<<<< HEAD - Validation: unmapped +======= +- Validation: validated (S01) — both plan-milestone.md and guided-plan-milestone.md contain forecasting instructions with {{secretsOutputPath}} variable, wired through auto.ts and guided-flow.ts +>>>>>>> gsd/M002/S01 - Notes: Modifies plan-milestone.md and possibly the discuss prompt. ### R010 — secure_env_collect enhanced with guidance field @@ -170,15 +186,25 @@ This file is the explicit capability and coverage contract for the project. | ID | Class | Status | Primary owner | Supporting | Proof | |---|---|---|---|---|---| +<<<<<<< HEAD | R001 | core-capability | active | M002/S01 | M002/S03 | unmapped | | R002 | continuity | active | M002/S01 | M002/S02, M002/S03 | unmapped | | R003 | primary-user-loop | active | M002/S01 | M002/S02 | unmapped | +======= +| R001 | core-capability | active | M002/S01 | M002/S03 | contract-proven (S01) | +| R002 | continuity | active | M002/S01 | M002/S02, M002/S03 | contract-proven (S01) | +| R003 | primary-user-loop | active | M002/S01 | M002/S02 | contract-proven (S01) | +>>>>>>> gsd/M002/S01 | R004 | primary-user-loop | active | M002/S02 | none | unmapped | | R005 | primary-user-loop | active | M002/S02 | none | unmapped | | R006 | integration | active | M002/S02 | M002/S03 | unmapped | | R007 | core-capability | active | M002/S03 | none | unmapped | | R008 | core-capability | active | M002/S03 | none | unmapped | +<<<<<<< HEAD | R009 | integration | active | M002/S01 | none | unmapped | +======= +| R009 | integration | validated | M002/S01 | none | validated (S01) | +>>>>>>> gsd/M002/S01 | R010 | primary-user-loop | active | M002/S02 | none | unmapped | | R011 | core-capability | deferred | none | none | unmapped | | R012 | operability | deferred | none | none | unmapped | @@ -187,7 +213,14 @@ This file is the explicit capability and coverage contract for the project. ## Coverage Summary +<<<<<<< HEAD - Active requirements: 10 - Mapped to slices: 10 - Validated: 0 +======= +- Active requirements: 9 +- Mapped to slices: 10 +- Validated: 1 (R009) +- Contract-proven: 3 (R001, R002, R003) +>>>>>>> gsd/M002/S01 - Unmapped active requirements: 0 diff --git a/.gsd/STATE.md b/.gsd/STATE.md index f602821be..c6588206d 100644 --- a/.gsd/STATE.md +++ b/.gsd/STATE.md @@ -2,6 +2,7 @@ **Active Milestone:** M002 — Proactive Secret Management <<<<<<< HEAD +<<<<<<< HEAD **Active Slice:** — **Active Task:** — **Phase:** pre-planning @@ -23,6 +24,8 @@ - (none) ======= +======= +>>>>>>> gsd/M002/S01 **Active Slice:** S02 — Enhanced Collection UX **Phase:** planning **Requirements Status:** 10 active · 0 validated · 2 deferred · 2 out of scope @@ -39,4 +42,7 @@ ## Next Action Plan slice S02 (Enhanced Collection UX). +<<<<<<< HEAD +>>>>>>> gsd/M002/S01 +======= >>>>>>> gsd/M002/S01 diff --git a/scripts/postinstall.js b/scripts/postinstall.js index edbb73922..f22573d3e 100644 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -22,6 +22,7 @@ function run(cmd, options = {}) { }) } <<<<<<< HEAD +<<<<<<< HEAD // --------------------------------------------------------------------------- // Redirect stdout → stderr so npm always shows postinstall output. @@ -60,6 +61,9 @@ const banner = ======= +======= + +>>>>>>> gsd/M002/S01 // --------------------------------------------------------------------------- // Redirect stdout → stderr so npm always shows postinstall output. // npm ≥7 suppresses stdout from lifecycle scripts by default; stderr is @@ -73,28 +77,41 @@ process.stdout.write = process.stderr.write.bind(process.stderr) ;(async () => { let p, pc +<<<<<<< HEAD +>>>>>>> gsd/M002/S01 +======= >>>>>>> gsd/M002/S01 try { p = await import('@clack/prompts') pc = (await import('picocolors')).default } catch { // Clack or picocolors unavailable — fall back to minimal output +<<<<<<< HEAD <<<<<<< HEAD process.stderr.write(` Run gsd to get started.\n\n`) await run('npx patch-package') await run('npx playwright install chromium') ======= +======= +>>>>>>> gsd/M002/S01 process.stderr.write(`\n GSD v${pkg.version} installed.\n Run gsd to get started.\n\n`) await run('npx patch-package') const args = os.platform() === 'linux' ? '--with-deps' : '' await run(`npx playwright install chromium ${args}`) +<<<<<<< HEAD +>>>>>>> gsd/M002/S01 +======= >>>>>>> gsd/M002/S01 return } // --- Branded intro ------------------------------------------------------- +<<<<<<< HEAD <<<<<<< HEAD p.intro('Setup') +======= + p.intro(pc.bgCyan(pc.black(' gsd ')) + ' ' + pc.dim(`v${pkg.version}`)) +>>>>>>> gsd/M002/S01 ======= p.intro(pc.bgCyan(pc.black(' gsd ')) + ' ' + pc.dim(`v${pkg.version}`)) >>>>>>> gsd/M002/S01 @@ -117,11 +134,17 @@ process.stdout.write = process.stderr.write.bind(process.stderr) } // --- Step 2: Playwright browser ------------------------------------------ +<<<<<<< HEAD <<<<<<< HEAD // Avoid --with-deps: install scripts should not block on interactive sudo // prompts. If Linux libs are missing, suggest the explicit follow-up. s.start('Setting up browser tools…') const pwResult = await run('npx playwright install chromium') +======= + s.start('Setting up browser tools…') + const pwArgs = os.platform() === 'linux' ? ' --with-deps' : '' + const pwResult = await run(`npx playwright install chromium${pwArgs}`) +>>>>>>> gsd/M002/S01 ======= s.start('Setting up browser tools…') const pwArgs = os.platform() === 'linux' ? ' --with-deps' : '' @@ -131,6 +154,7 @@ process.stdout.write = process.stderr.write.bind(process.stderr) s.stop('Browser tools ready') results.push({ label: 'Browser tools ready', ok: true }) } else { +<<<<<<< HEAD <<<<<<< HEAD const output = `${pwResult.stdout ?? ''}${pwResult.stderr ?? ''}` if (os.platform() === 'linux' && output.includes('Host system is missing dependencies to run browsers.')) { @@ -147,11 +171,16 @@ process.stdout.write = process.stderr.write.bind(process.stderr) }) } ======= +======= +>>>>>>> gsd/M002/S01 s.stop(pc.yellow('Browser tools — skipped (non-fatal)')) results.push({ label: 'Browser tools unavailable — run ' + pc.cyan('npx playwright install chromium'), ok: false, }) +<<<<<<< HEAD +>>>>>>> gsd/M002/S01 +======= >>>>>>> gsd/M002/S01 } diff --git a/src/resources/extensions/gsd/tests/parsers.test.ts b/src/resources/extensions/gsd/tests/parsers.test.ts index 8b58a9b13..a30aae498 100644 --- a/src/resources/extensions/gsd/tests/parsers.test.ts +++ b/src/resources/extensions/gsd/tests/parsers.test.ts @@ -1250,6 +1250,7 @@ console.log('\n=== parseRequirementCounts: total is sum of all section counts == // ═══════════════════════════════════════════════════════════════════════════ <<<<<<< HEAD +<<<<<<< HEAD // parseSummary: bare scalar frontmatter fields (regression test for #91) // ═══════════════════════════════════════════════════════════════════════════ @@ -1342,6 +1343,8 @@ Nothing. assertEq(s.frontmatter.drill_down_paths.length, 0, 'missing drill_down_paths = empty array'); assertEq(s.frontmatter.observability_surfaces.length, 0, 'missing observability_surfaces = empty array'); ======= +======= +>>>>>>> gsd/M002/S01 // parseSecretsManifest / formatSecretsManifest tests // ═══════════════════════════════════════════════════════════════════════════ @@ -1579,6 +1582,9 @@ console.log('\n=== parseSecretsManifest + formatSecretsManifest: round-trip ===' assertEq(e2.guidance[j], e1.guidance[j], `round-trip entry ${i} guidance[${j}]`); } } +<<<<<<< HEAD +>>>>>>> gsd/M002/S01 +======= >>>>>>> gsd/M002/S01 }